我把Java類的初始化順序分為兩部分。第一部分是類的初始化,第二部分是對象的初始化。
在初始化之前JVM必須先把該類的位元組碼載入到記憶體中來。這時不管創不建立對象都會馬上執行類的初始化:
執行靜態初始設定式(如static int a = 10)和靜態初始化塊(即static{}中的內容),注意兩者按在原始碼中的先後順序執行。
當建立一個對象,就會執行對象的初始化:
首先調用父類的建構函式。
第二步執行初始設定式(如int a = 10)和初始化塊({}中的內容),同樣按在原始碼中的先後順序執行。
最後執行自身的建構函式。
對於靜態初始設定式與初始設定式,如果只是聲明,沒有初始化,則賦預設值。如int i;則i會被賦值為0。
總結:
1、 類初始化
(1) 靜態初始設定式,靜態初始化塊
2、對象初始化
(1)父類的建構函式
(2)初始設定式,初始化塊
(3)自身的建構函式
注意:初始設定式可能不是準確的術語,但明白是指什麼就行了。
測試代碼:
代碼package principle;
public class InitializeTest {
public static void main(String[] args) throws ClassNotFoundException{
System.out.println("-----類初始化-----");
Class.forName("principle.MyClass");
System.out.println("\n" + "-----對象初始化-----");
MyClass myClass = new MyClass();
}
}
class MyClass extends Father{
MyClass() {
System.out.println("3.自身的建構函式");
}
static int staticInt = 5; //如果放在static{}後面則編譯不通過
static {
System.out.print("1.靜態初始設定式:staticInt=" + staticInt + "\t");
System.out.println("靜態初始化塊");
}
int instanceInt; //將會被賦預設值0
{
System.out.print("2.初始設定式:instanceInt=" + instanceInt + "\t");
System.out.println("初始化塊");
}
}
class Father {
Father() {
System.out.println("1.父類的建構函式");
}
}
輸出結果:
-----類初始化-----
1.靜態初始設定式:staticInt=5 靜態初始化塊
-----對象初始化-----
1.父類的建構函式
2.初始設定式:instanceInt=0 初始化塊
3.自身的建構函式