經(jīng)典面試題:static加載機(jī)制你知道嗎?
經(jīng)典面試題:static加載機(jī)制你知道嗎?
static在Java中是一個(gè)很常見(jiàn)的關(guān)鍵字,同時(shí)它也是面試時(shí)的一個(gè)高頻考點(diǎn)。那么在Java類(lèi)中,static的加載機(jī)制到底是怎樣的呢?接下來(lái)小編就來(lái)帶大家弄明白這個(gè)問(wèn)題。
一. 類(lèi)加載機(jī)制
JVM在首次使用某個(gè)類(lèi)時(shí),會(huì)通過(guò) classpath 來(lái)查找該類(lèi)的.class文件。然后將.class文件中對(duì)類(lèi)的描述信息加載到內(nèi)存中進(jìn)行保存,如:包名、類(lèi)名、父類(lèi)、屬性、方法、構(gòu)造方法......一個(gè)類(lèi)的加載過(guò)程大致如下:
加載時(shí)機(jī)
創(chuàng)建對(duì)象
創(chuàng)建子類(lèi)對(duì)象
訪問(wèn)靜態(tài)屬性
調(diào)用靜態(tài)方法
主動(dòng)加載:Class.forName(“全限定名”)
二. static 特點(diǎn)
被static關(guān)鍵字修飾的類(lèi)或方法、成員等具有如下特點(diǎn):
靜態(tài)方法允許直接訪問(wèn)靜態(tài)成員;
靜態(tài)方法不能直接訪問(wèn)非靜態(tài)成員;
靜態(tài)方法中不允許使用this或是super關(guān)鍵字;
靜態(tài)方法可以繼承,不能重寫(xiě)、沒(méi)有多態(tài)。
三. 經(jīng)典面試題
接著我們?cè)賮?lái)看看關(guān)于static的一個(gè)經(jīng)典面試題,代碼案例如下:
public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("構(gòu)造代碼塊");
}
static{
print("靜態(tài)構(gòu)造代碼塊");
}
public Test(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
public static void main(String[] args) {
}
}
這是一道關(guān)于static加載執(zhí)行順序的經(jīng)典面試題,根據(jù)代碼觀察執(zhí)行結(jié)果,接下來(lái)我們就來(lái)分析一下上述代碼的執(zhí)行結(jié)果是什么。
在執(zhí)行 main 方法,也就是程序主入口的時(shí)候,首先會(huì)加載所在的類(lèi),聲明靜態(tài)變量,初始化靜態(tài)屬性,執(zhí)行靜態(tài)代碼塊(按照順序執(zhí)行),所以首先加載的是:
public static int k = 0;
2. 其次加載:
public static Test t1 = new Test("t1");
3. 而加載到實(shí)例化 t1 對(duì)象時(shí),類(lèi)的加載會(huì)暫停,然后創(chuàng)建 Test 的實(shí)例對(duì)象。在創(chuàng)建 Test 對(duì)象時(shí)則會(huì)先加載屬性再執(zhí)行代碼塊,最后執(zhí)行構(gòu)造方法,所以先執(zhí)行的會(huì)是實(shí)例屬性。
private int a = 0;
public int j = print("j");
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
4. 因加載類(lèi)的過(guò)程中,會(huì)對(duì)定義的靜態(tài)字段在方法區(qū)中分別分配空間,并賦予初始化值,所以 i 和 n 的值都為0,因此第一個(gè)打印語(yǔ)句是:
1:j i=0 n=0
5. 實(shí)例屬性加載完畢后,則進(jìn)行構(gòu)造代碼塊的加載:
{
print("構(gòu)造代碼塊");
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
6. 因?yàn)榈谝淮握{(diào)用時(shí)已經(jīng)對(duì) k 、i 、n 的值進(jìn)行了自加,因此第二個(gè)打印語(yǔ)句是:
2:構(gòu)造代碼塊 i=1 n=1
7. 實(shí)例化對(duì)象的最后一步,則是執(zhí)行構(gòu)造方法:
public static Test t1 = new Test("t1");
public Test(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
8. 因此第三個(gè)打印語(yǔ)句是:
3:t1 i=2 n=2
9. t1 對(duì)象創(chuàng)建完畢后,類(lèi)加載則繼續(xù)執(zhí)行,因此下一步則是:
public static Test t2 = new Test("t2");
10. 按照前面實(shí)例化 t1 的執(zhí)行機(jī)制,因此接下來(lái)的打印的幾句則是:
4:j i=3 n=3
5:構(gòu)造代碼塊 i=4 n=4
6:t2 i=5 n=5
11. 實(shí)例化完 t2 對(duì)象后,繼續(xù)進(jìn)行類(lèi)加載,因此下一步加載靜態(tài)屬性 i 的賦值:
public static int i = print("i");
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
12. 因此下一步打印結(jié)果為:
7:i i=6 n=6
13. 加載完最后一個(gè)靜態(tài)屬性 n= 99 后,則加載靜態(tài)構(gòu)造代碼塊:
public static int n = 99;
static{
print("靜態(tài)構(gòu)造代碼塊");
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
13. 因此最后會(huì)打印:
8:靜態(tài)構(gòu)造代碼塊 i=7 n=99
14. 所以整體的執(zhí)行結(jié)果會(huì)是:
1:j i=0 n=0
2:構(gòu)造代碼塊 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:構(gòu)造代碼塊 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:靜態(tài)構(gòu)造代碼塊 i=7 n=99
四. 小結(jié)
現(xiàn)在你知道一個(gè)Java類(lèi)的加載執(zhí)行機(jī)制了嗎?可以說(shuō),掌握 static 在程序中的加載執(zhí)行順序,可以使我們更好地理解代碼,明白程序的執(zhí)行流程。今天小編只是通過(guò)這樣的一個(gè)小案例,給大家展現(xiàn)了 static 使用的冰山一角,它還有更多的神奇之處有待于我們繼續(xù)挖掘,請(qǐng)大家繼續(xù)關(guān)注小編哦。

猜你喜歡LIKE
相關(guān)推薦HOT
更多>>
SEO優(yōu)化
SEO優(yōu)化,1、合理的title、description、keywords:搜索對(duì)著三項(xiàng)的權(quán)重逐個(gè)減小,title值強(qiáng)調(diào)重點(diǎn)即可;description把頁(yè)面內(nèi)容高度概括,不可過(guò)...詳情>>
2023-04-03 15:11:51
Python數(shù)據(jù)生產(chǎn)器
Python數(shù)據(jù)生產(chǎn)器,在軟件開(kāi)發(fā)、測(cè)試或者數(shù)據(jù)分析過(guò)程中,有時(shí)候會(huì)需要一些測(cè)試數(shù)據(jù)。做測(cè)試的時(shí)候,需要模擬真實(shí)的環(huán)境,但是又不能直接使用真...詳情>>
2023-03-28 15:56:13
Java集合是什么?Java集合詳解
Java集合是Java編程語(yǔ)言中的一個(gè)重要概念,用于存儲(chǔ)、管理和處理數(shù)據(jù)。Java集合框架提供了一組接口和類(lèi),用于實(shí)現(xiàn)常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),如列表、棧、...詳情>>
2023-03-20 19:12:47
js查找字符串中指定字符的位置
另外,如果要查找一個(gè)字符串中所有出現(xiàn)的指定字符的位置,可以使用indexOf()方法結(jié)合循環(huán)來(lái)實(shí)現(xiàn)。然后,我們使用循環(huán)遍歷字符串中的每一個(gè)字符...詳情>>
2023-03-10 14:06:35熱門(mén)推薦
跨域如何解決
沸SEO優(yōu)化
熱Null和undefined的區(qū)別
熱Python數(shù)據(jù)生產(chǎn)器
新react中怎么實(shí)現(xiàn)vue中的計(jì)算屬性以及watch
經(jīng)典面試題:static加載機(jī)制你知道嗎?
消息中間件常用協(xié)議有哪些
Java集合是什么?Java集合詳解
線程池實(shí)現(xiàn)原理
java數(shù)據(jù)結(jié)構(gòu)與算法
Java到底有多難?
js查找字符串中指定字符的位置
jquery獲取checkbox是否選中
四種方式創(chuàng)建SpringBoot項(xiàng)目
技術(shù)干貨







快速通道 更多>>
-
課程介紹
點(diǎn)擊獲取大綱 -
就業(yè)前景
查看就業(yè)薪資 -
學(xué)習(xí)費(fèi)用
了解課程價(jià)格 -
優(yōu)惠活動(dòng)
領(lǐng)取優(yōu)惠券 -
學(xué)習(xí)資源
領(lǐng)3000G教程 -
師資團(tuán)隊(duì)
了解師資團(tuán)隊(duì) -
實(shí)戰(zhàn)項(xiàng)目
獲取項(xiàng)目源碼 -
開(kāi)班地區(qū)
查看來(lái)校路線