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

相關推薦HOT
更多>>
SEO優化
SEO優化,1、合理的title、description、keywords:搜索對著三項的權重逐個減小,title值強調重點即可;description把頁面內容高度概括,不可過...詳情>>
2023-04-03 15:11:51
Python數據生產器
Python數據生產器,在軟件開發、測試或者數據分析過程中,有時候會需要一些測試數據。做測試的時候,需要模擬真實的環境,但是又不能直接使用真...詳情>>
2023-03-28 15:56:13
Java集合是什么?Java集合詳解
Java集合是Java編程語言中的一個重要概念,用于存儲、管理和處理數據。Java集合框架提供了一組接口和類,用于實現常見的數據結構,如列表、棧、...詳情>>
2023-03-20 19:12:47
js查找字符串中指定字符的位置
另外,如果要查找一個字符串中所有出現的指定字符的位置,可以使用indexOf()方法結合循環來實現。然后,我們使用循環遍歷字符串中的每一個字符...詳情>>
2023-03-10 14:06:35