對於靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序以此是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器。我們也可以通過下面的測試代碼來驗證這一點:
package InitialOrder; /** * JAVA 初始化順序 * @author Administrator * 初始化順序依次是(靜態變量、靜態初始化塊)>(變量、初始化塊)> 構造器。 */ public class InitialOrderTest { // 靜態變量 public static String staticField = "靜態變量"; // 變量 public String field = "變量"; // 構造器 public InitialOrderTest() { System.out.println("構造器"); } // 初始化塊 { System.out.println(field); System.out.println("初始化塊"); } // 靜態初始化塊 static { System.out.println(staticField); System.out.println("靜態初始化塊"); } public static void main(String[] args) { new InitialOrderTest(); } /** * 輸出結果爲: * 靜態變量 * 靜態初始化塊 * 變量 * 初始化塊 * 構造器 */ }
對於繼承情況下又會怎樣呢?我們仍然以一段測試代碼來獲取最終結果:
package InitialOrder; class Parent { // 靜態變量 public static String p_StaticField = "父類--靜態變量"; // 變量 public String p_Field = "父類--變量"; // 構造器 public Parent() { System.out.println("父類--構造器"); } // 初始化塊 { System.out.println(p_Field); System.out.println("父類--初始化塊"); } // 靜態初始化塊 static { System.out.println(p_StaticField); System.out.println("父類--靜態初始化塊"); } } /** * 對於繼承情況下,靜態變量、靜態初始化塊、變量、初始化塊、構造器的執行順序是什麼樣的呢? * @author Administrator * 並不是父類完全初始化完畢後才進行子類的初始化, * 實際上子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。 * */ public class SubClass extends Parent { // 靜態變量 public static String s_StaticField = "子類--靜態變量"; // 變量 public String s_Field = "子類--變量"; // 構造器 public SubClass() { System.out.println("子類--構造器"); } // 初始化塊 { System.out.println(s_Field); System.out.println("子類--初始化塊"); } // 靜態初始化塊 static { System.out.println(s_StaticField); System.out.println("子類--靜態初始化塊"); } // 程序入口 public static void main(String[] args) { new SubClass(); } /** * 輸出結果: * 父類--靜態變量 * 父類--靜態初始化塊 * 子類--靜態變量 * 子類--靜態初始化塊 * 父類--變量 * 父類--初始化塊 * 父類--構造器 * 子類--變量 * 子類--初始化塊 * 子類--構造器 */ }
現在,結果已經不言自明瞭。大家可能會注意到一點,那就是,並不是父類完全初始化完畢後才進行子類的初始化,實際上子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。
那麼對於靜態變量和靜態初始化塊之間、變量和初始化塊之間的先後順序又是怎樣呢?是否靜態變量總是先於靜態初始化塊,變量總是先於初始化塊就被初始化了呢?實際上這取決於它們在類中出現的先後順序。我們以靜態變量和靜態初始化塊爲例來進行說明:
package InitialOrder; class TestA { public TestA() { System.out.println("Test--A"); } } class TestB { public TestB() { System.out.println("Test--B"); } } /** * 對於靜態變量與靜態初始化塊的執行順序 * @author Administrator * 靜態變量和靜態初始化塊是依照他們在類中的定義順序進行初始化的。 * 同樣,變量和初始化塊也遵循這個規律。 */ public class TestOrder { // 靜態變量 public static TestA a = new TestA(); // 靜態初始化塊 static { System.out.println("靜態初始化塊"); } // 靜態變量 public static TestB b = new TestB(); public static void main(String[] args) { new TestOrder(); } /** * 輸出結果: * Test--A * 靜態初始化塊 * Test--B */ }
大家可以隨意改變變量a、變量b以及靜態初始化塊的前後位置,就會發現輸出結果隨着它們在類中出現的前後順序而改變,這就說明靜態變量和靜態初始化塊是依照他們在類中的定義順序進行初始化的。同樣,變量和初始化塊也遵循這個規律。