類的初始化順序
這幾天看java編程思想內(nèi)部類這節(jié)時,其中有個例子(第4版213頁)的輸出跟自己的預(yù)期有點出入曾沈,手動debug了一遍这嚣,發(fā)現(xiàn)是自己對類的初始化順序理解不到位,于是重新將類的初始化順序梳理了一番塞俱。
話不多說姐帚,先看結(jié)論:
- 父類靜態(tài)域 > 子類靜態(tài)域 > 父類非靜態(tài)域 > 父類構(gòu)造函數(shù) > 子類非靜態(tài)域 > 子類構(gòu)造函數(shù)。
- 如果有多個靜態(tài)域或多個非靜態(tài)域障涯,則按聲明順序依次執(zhí)行罐旗。
- 當(dāng)?shù)谝淮握{(diào)用靜態(tài)函數(shù)時,會觸發(fā)其他靜態(tài)域的初始化唯蝶,然后再執(zhí)行該函數(shù)中的代碼九秀。
證明示例如下:
首先,來看沒有繼承的情況
public class TestClassInit {
public static void main(String[] args) {
new Test();
}
}
class A{
public A(int i){
System.out.println("("+i+")");
}
}
class Test{
static {
System.out.println("靜態(tài)塊1...");
}
{
System.out.println("非靜態(tài)塊1...");
}
static A a1 = new A(1);
A a2 = new A(2);
{
System.out.println("非靜態(tài)塊2...");
}
A a3 = new A(3);
static {
System.out.println("靜態(tài)塊2...");
}
static A a4 = new A(4);
static void f(){
System.out.println("f()");
}
}
輸出結(jié)果為:
靜態(tài)塊1...
(1)
靜態(tài)塊2...
(4)
非靜態(tài)塊1...
(2)
非靜態(tài)塊2...
(3)
將上述代碼稍作改動粘我,new Test();
換成Test.f();
輸出結(jié)果為:
靜態(tài)塊1...
(1)
靜態(tài)塊2...
(4)
f()
再看有繼承的情況
public class TestClassInitWithExtend {
public static void main(String[] args) {
new Son();
}
}
class Parent{
public Parent(){
System.out.println("New Parent()");
}
A a1 = new A (1);
static A a2 = new A(2);
}
class Son extends Parent{
public Son(){
System.out.println("New Son()");
}
static A a3 = new A(3);
A a4 = new A(4);
}
輸出結(jié)果為:
(2)
(3)
(1)
New Parent()
(4)
New Son()