Java類初始化順序

先不考慮父類。初始化的一個大原則是:

(1)靜態域成員(靜態變量和靜態代碼塊)最先;

(2)非靜態域成員(成員變量和初始化代碼塊)先於構造函數;

(3)同是靜態域成員或同是非靜態域成員,則先後順序和代碼順序一致

public class InitialOrder {

    private static String staticField = "Static Field Initial";

    private String field = "Field Initial";

    static {
        System.out.println(staticField);
        System.out.println("Static Patch Initial");
    }

    {
        System.out.println(field);
        System.out.println("Field Patch Initial");
    }

    public InitialOrder() {
        System.out.println("Structure Initial ");
    }

    public static void main(String[] argc) {
        new InitialOrder();
    }
}

輸出:

Static Field Initial (靜態變量) 
Static Patch Initial (靜態初始化塊) 
Field Initial (變量) 
Field Patch Initial (初始化塊) 
Structure Initial (構造器)

然後考慮下父類。在上面的原則下再加一條:

(1)靜態域的初始化一定是最先開始的;(當然,已經初始化過了就不再初始化了)

(2)要初始化子類,一定要先初始化父類。

public class ParentInitialOrder {
    private static String staticField = "Parent Static Field Initial";

    private String field = "Parent Field Initial";

    static {
        System.out.println(staticField);
        System.out.println("Parent Static Patch Initial");
    }

    {
        System.out.println(field);
        System.out.println("Parent Field Patch Initial");
    }

    public ParentInitialOrder() {
        System.out.println("Parent Structure Initial ");
    }

}

public class ChildInitialOrder extends ParentInitialOrder {
    private static String staticField = "Child Static Field Initial";

    private String field = "Child Field Initial";

    static {
        System.out.println(staticField);
        System.out.println("Child Static Patch Initial");
    }

    {
        System.out.println(field);
        System.out.println("Child Field Patch Initial");
    }

    public ChildInitialOrder() {
        System.out.println("Child Structure Initial ");
    }

    public static void main(String argv[]) {
        new ChildInitialOrder();
    }
}
Parent Static Field Initial (父類靜態變量)
Parent Static Patch Initial (父類靜態初始化塊)
Child Static Field Initial (子類靜態變量)
Child Static Patch Initial (子類靜態代碼塊)
Parent Field Initial (父類變量)
Parent Field Patch Initial (父類初始化塊)
Parent Structure Initial (父類構造函數)
Child Field Initial (子類變量)
Child Field Patch Initial (子類初始化塊)
Child Structure Initial(子類構造函數)

測試題:

public class InitialOrderTest {
    public static int k = 0;
    public static InitialOrderTest t1 = new InitialOrderTest("t1");
    public static InitialOrderTest t2 = new InitialOrderTest("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");

    static {
        print("靜態塊");
    }

    {
        print("構造塊");
    }

    public InitialOrderTest(String str) {
        System.out.println((++k) + ":" + str + "    i=" + i + "    n=" + n);
        ++i;
        ++n;
    }

    public static int print(String str) {
        System.out.println((++k) + ":" + str + "    i=" + i + "    n=" + n);
        ++n;
        return ++i;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        InitialOrderTest t = new InitialOrderTest("init");
    }
}

答案:

  1. j i=0 n=0
  2. 構造塊 i=1 n=1
  3. t1 i=2 n=2
  4. j i=3 n=3
  5. 構造塊 i=4 n=4
  6. t2 i=5 n=5
  7. i i=6 n=6
  8. 靜態塊 i=7 n=99
  9. j i=8 n=100
  10. 構造塊 i=9 n=101
  11. init i=10 n=102
發佈了94 篇原創文章 · 獲贊 43 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章