最近發現微信群裡面有些群友在讨論類的初始化順序,如類的靜态變量、成員變量、靜态代碼塊、非靜态代碼塊、構造器,及繼承父類時,它們的初始化順序都是怎樣的,下面我通過例子來說明這個情況,以免被人誤導。
示例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
是以,它們的在類中的順序就決定了它們的初始化順序,而不是變量一定會優先于初始塊。