Java的靜態變量,成員變量,靜態代碼塊,構造快的加載順序
今天在看靜態代碼塊執行順序相關文章時遇到一個挺有意思的題目,題目如下:
public class StaticTest{
static StaticTest st = new StaticTest();
public static void staticFunction(){
System.out.println("4");
}
static{
System.out.println("1");
}
StaticTest(){
System.out.println("3");
System.out.println("a="+a+" b="+b);
}
int a=100;
static int b=112;
{
System.out.println("2");
}
public static void main(String args[]){
staticFunction();
}
}
猜一下執行後在控制檯打印的結果,剛開始看到後認爲順序應該是這樣的:
1
2
3
a=100 b=112
4
但是實際上運行後的結果是這樣的:
2
3
a=100 b=0
1
4
後來看了分析,原來過程是這樣的:
類的生命週期是:加載->驗證->準備->解析->初始化->使用->卸載
準備和初始化階段涉及類變量的初始化和賦值
準備階段:爲static類變量分配內存並設置默認值,st = null b = 0
初始化階段:
執行類構造器
先按順序執行靜態變量,static StaticTest st = new StaticTest();
然後會執行StaticTest()方法,執行前先執行構造代碼塊再初始化成員變量,所以先輸出2,a=100,b由於已經初始化完畢,不執行
執行StaticTest()中的輸出3,,a=100,b=0
StaticTest()執行完之後,順序執行static代碼塊,輸出1
main中調用staticfunction 輸出4
所以執行代碼時候打斷點看到的順序是這樣的:
執行構造代碼塊——》初始化成員變量——》執行static變量初始化——》執行靜態變量——》執行方法——》繼續執行static代碼塊——》main調用方法;
通過這短短几行代碼對類加載順序有了更深刻的瞭解。