轉自:http://zangweiren.iteye.com/blog/208122
對于靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序以此是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器。我們也可以通過下面的測試代碼來驗證這一點:?Java代碼
??? public class InitialOrderTest {
??????? // 靜態變量
??????? public static String staticField = "靜態變量";
??????? // 變量
??????? public String field = "變量";
??????? // 靜態初始化塊
??????? static {
??????????? System.out.println(staticField);
??????????? System.out.println("靜態初始化塊");
??????? }
??????? // 初始化塊
??????? {
??????????? System.out.println(field);
??????????? System.out.println("初始化塊");
??????? }
??????? // 構造器
??????? public InitialOrderTest() {
??????????? System.out.println("構造器");
??????? }
??????? public static void main(String[] args) {
??????????? new InitialOrderTest();
??????? }
??? }
??? 運行以上代碼,我們會得到如下的輸出結果:
??? 靜態變量
??? 靜態初始化塊
??? 變量
??? 初始化塊
??? 構造器
??? 這與上文中說的完全符合。
?
那么對于繼承情況下又會怎樣呢?我們仍然以一段測試代碼來獲取最終結果: Java代碼
??? class Parent {
??????? // 靜態變量
??????? public static String p_StaticField = "父類--靜態變量";
??????? // 變量
??????? public String p_Field = "父類--變量";
??????? // 靜態初始化塊
??????? static {
??????????? System.out.println(p_StaticField);
??????????? System.out.println("父類--靜態初始化塊");
??????? }
??????? // 初始化塊
??????? {
??????????? System.out.println(p_Field);
??????????? System.out.println("父類--初始化塊");
??????? }
??????? // 構造器
??????? public Parent() {
??????????? System.out.println("父類--構造器");
??????? }
??? }
??? public class SubClass extends Parent {
??????? // 靜態變量
??????? public static String s_StaticField = "子類--靜態變量";
??????? // 變量
??????? public String s_Field = "子類--變量";
??????? // 靜態初始化塊
??????? static {
??????????? System.out.println(s_StaticField);
??????????? System.out.println("子類--靜態初始化塊");
??????? }
// 初始化塊
??????? {
??????????? System.out.println(s_Field);
??????????? System.out.println("子類--初始化塊");
??????? }
??????? // 構造器
??????? public SubClass() {
??????????? System.out.println("子類--構造器");
??????? }
??????? // 程序入口
??????? public static void main(String[] args) {
??????????? new SubClass();
??????? }
??? }
???? 運行一下上面的代碼,結果馬上呈現在我們的眼前:
??? 父類--靜態變量
??? 父類--靜態初始化塊
??? 子類--靜態變量
??? 子類--靜態初始化塊
??? 父類--變量
??? 父類--初始化塊
??? 父類--構造器
??? 子類--變量
??? 子類--初始化塊
??? 子類--構造器
??? 現在,結果已經不言自明了。大家可能會注意到一點,那就是,并不是父類完全初始化完畢后才進行子類的初始化,實際上子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。 那么對于靜態變量和靜態初始化塊之間、變量和初始化塊之間的先后順序又是怎樣呢?是否靜態變量總是先于靜態初始化塊,變量總是先于初始化塊就被初始化了呢?實際上這取決于它們在類中出現的先后順序。我們以靜態變量和靜態初始化塊為例來進行說明。 同樣,我們還是寫一個類來進行測試: Java代碼
??? 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();
??????? }
??? }
??? class TestA {
??????? public TestA() {
??????????? System.out.println("Test--A");
??????? }
??? }
??? class TestB {
??????? public TestB() {
??????????? System.out.println("Test--B");
??????? }
??? }
???? 運行上面的代碼,會得到如下的結果:
??? Test--A
??? 靜態初始化塊
??? Test--B
??? 大家可以隨意改變變量a、變量b以及靜態初始化塊的前后位置,就會發現輸出結果隨著它們在類中出現的前后順序而改變,這就說明靜態變量和靜態初始化塊是依照他們在類中的定義順序進行初始化的。同樣,變量和初始化塊也遵循這個規律。 了解了繼承情況下類的初始化順序之后,如何判斷最終輸出結果就迎刃而解了。