jvm-008
一、初始化的執行順序:類的初始化順序是按照代碼邏輯自上而下依次執行的。
代碼1:
public class TestCode06 {
public static void main(String[] args) {
MyParent06 instance = MyParent06.getInstance();
System.out.println("a : " + instance.a);//1
System.out.println("b : " + instance.b);//0
}
}
class MyParent06 {
public static int a;
public static int b = 0;
public static MyParent06 mp = new MyParent06();
public MyParent06() {
a ++ ;
b ++ ;
}
public static MyParent06 getInstance() {
return mp;
}
}
運行結果:
a : 1
b : 1
分析:首先進行類的加載、連接、初始化,在連接的準備階段,對類的靜態變量賦予零值,準備階段過後,a = 0, b = 0, mp = null。在main方法中,MyParent06 instance = MyParent06.getInstance()代碼執行的時候,會執行 MyParent06 類中 mp = new MyParent06(),會引發 MyParent06 類的初始化。初始化順序分別是 a 不賦值, b = 0,mp = new MyParent06()會執行,在執行這一步的時候,會調用 MyParent06 類的實例代碼塊 {
a ++ ;
b ++ ;
}, 執行過後,a 和 b的值分別爲 a = 1, b = 1,所以在main方法中, 在獲取 instance.a / instance.b的數值的時候,結果都是1。
============================分割符==============================
代碼2:
public class TestCode06 {
public static void main(String[] args) {
MyParent06 instance = MyParent06.getInstance();
System.out.println("a : " + instance.a);//1
System.out.println("b : " + instance.b);//0
}
}
class MyParent06 {
public static int a;
public static MyParent06 mp = new MyParent06();
public static int b = 0;
public MyParent06() {
a ++ ;
b ++ ;
}
public static MyParent06 getInstance() {
return mp;
}
}
運行結果:
a : 1
b : 0
分析:代碼2與代碼1的唯一區別就是
public static MyParent06 mp = new MyParent06() 和 public static int b = 0的順序發生了變化,但是結果就不一樣了。
同代碼的原理:MyParent06 類首先被加載,加載過後的 a = 0, b = 0, mp = null;之後再main方法中執行 MyParent06 instance = MyParent06.getInstance() 會觸發 MyParent06 類的初始化,初始化順序與代碼1有所不同:
首先 a 不賦值,仍舊是0,然後 是 mp = new MyParent06();此時創建對象會調用 MyParent06 類的實例代碼塊 {
a ++ ;
b ++ ;
},執行過後, a = 1, b = 1。再後面執行 int b = 0 的賦值過程,b又變爲0。所以在main方法中,打印結果 instance.a = 1, instance.b = 0;