static { b = "string-b"; printStatic("after static"); }
public static void printStatic(String title) { System.out.println("---------" + title + "---------"); System.out.println("a = /"" + a + "/""); System.out.println("b = /"" + b + "/""); }
public Test() { print("before constrUCtor"); d = "string-d"; print("after constructor"); }
public void print(String title) { System.out.println("---------" + title + "---------"); System.out.println("a = /"" + a + "/""); System.out.println("b = /"" + b + "/""); System.out.println("c = /"" + c + "/""); System.out.println("d = /"" + d + "/""); }
public static void main(String[] args) { new Test(); }
}
首先,我把 main() 方法注釋掉,運行結果如下:
---------before static--------- a = "string-a" b = "null" ---------after static--------- a = "string-a" b = "string-b" java.lang.NoSuchMethodError: main Exception in thread "main" Process completed.
然后,取消對 main() 方法的注釋,運行結果如下:
---------before static--------- a = "string-a" b = "null" ---------after static--------- a = "string-a" b = "string-b" ---------before constructor--------- a = "string-a" b = "string-b" c = "stirng-c" d = "null" ---------after constructor--------- a = "string-a" b = "string-b" c = "stirng-c" d = "string-d"
由此可以看出 Java 類屬性和對象屬性的初始化順序如下:
?、?類屬性 (靜態變量) 定義時的初始化,如上例的 static String a = "string-a"; ?、?static 塊中的初始化代碼,如上例 static {} 中的 b = "string-b"; ?、?對象屬性 (非靜態變量) 定義時的初始化,如上例的 String c = "stirng-c"; ④ 構造方法 (函數) 中的初始化代碼,如上例構造方法中的 d = "string-d";
在此過程中 ② 和 ③ 的順序無所確定,因為在靜態塊中無法打印出非靜態變量。同樣是因為這個原因,知道他們的順序對我們寫程序也毫無幫助。再因為類成員 (靜態成員) 是在第一次使用到類的時候就進行了相應的初始化,而對象成員 (非靜態成員) 則需要生成類實例 (即對象) 時才能初始化,所以我把 ③ 排在了 ② 的后面。再申明一次,它們究竟誰先誰后,從代碼上是不能確定的,恐怕需要去研究一下 JVM (Java 虛擬機) 的執行過程才行。