天天看點

Java類初始化順序,大神3個示例帶你躺坑。。

最近發現微信群裡面有些群友在讨論類的初始化順序,如類的靜态變量、成員變量、靜态代碼塊、非靜态代碼塊、構造器,及繼承父類時,它們的初始化順序都是怎樣的,下面我通過例子來說明這個情況,以免被人誤導。

示例1:測試單類的初始化順序

public class ClassInitOrderTest {

    public static String staticField = "static field";

    static {
        System.out.println(staticField);
        System.out.println("static block");
    }

    private String field = "member field";

    {
        System.out.println(field);
        System.out.println("non-static block");
    }

    public ClassInitOrderTest() {
        System.out.println("constructor");
    }

    public static void main(String[] args) {
        new ClassInitOrderTest();
    }

}      

程式輸出:

static field
static block
member field
non-static block
constructor      

可以得出以下結論,單類的初始化順序為:

靜态變量 > 靜态初始塊 > 成員變量 > 非靜态初始塊 > 構造器

示例2:測試類繼承的初始化順序

class Parent {

    private static String parentStaticField = "parent static field";

    static {
        System.out.println(parentStaticField);
        System.out.println("parent static block");
    }

    private String parentField = "parent member field";

    {
        System.out.println(parentField);
        System.out.println("parent non-static block");
    }

    public Parent() {
        System.out.println("parent constructor");
    }

}

public class Child extends Parent {

    private static String childStaticField = "child static field";

    static {
        System.out.println(childStaticField);
        System.out.println("child static block");
    }

    private String childField = "child member field";

    {
        System.out.println(childField);
        System.out.println("child non-static block");
    }

    public Child() {
        System.out.println("child constructor");
    }

    public static void main(String[] args) {
        new Child();
    }

}      
parent static field
parent static block
child static field
child static block
parent member field
parent non-static block
parent constructor
child member field
child non-static block
child constructor      

父類靜态變量 > 父類靜态初始塊 > 子類靜态變量 > 子類靜态初始塊 > 父類成員變量 > 父類非靜态初始塊 > 父類構造器 > 子類成員變量 > 子類非靜态初始塊 > 子類構造器

示例3:測試成員變量、初始塊的初始化順序

從上面兩個例子可以看出,父類的靜态變量和靜态初始塊肯定是先于子類加載的。但同一個類中的靜态變量與靜态初始塊之間,成員變量與初始塊之間的順序一定是變量先于初始塊嗎?繼續示範!

public class TestOrder {

    private static A a = new A();

    static {
        System.out.println("static block");
    }

    private static B b = new B();

    public static void main(String[] args) {
        new TestOrder();
    }

}

class A {
    public A() {
        System.out.println("static field A");
    }
}

class B {
    public B() {
        System.out.println("static field B");
    }
}      
static field A
static block
static field B      
靜态變量A > 靜态初始塊 > 靜态變量B

是以,它們的在類中的順序就決定了它們的初始化順序,而不是變量一定會優先于初始塊。