Java初始化
總結:初始化順序:父類靜態變量——> 父類靜態代碼塊 ——>子類靜態變量 ——> 子類靜態代碼塊 ——>父類非靜態變量 ——>父類構造代碼塊——> 父類構造函數 ——>字類非靜態變量 ——>子類構造代碼塊——> 子類構造函數
靜態代碼塊只會被執行一次!!!!
1. 關鍵:Java一個類的成員變量初始化先於構造函數執行。詳細請參考:
參考博客:傳送門
2. 該代碼爲何輸出:YXYZ
class X{
Y y=new Y();
public X(){
System.out.print("X");
}
}
class Y{
public Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();
public Z(){
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
3.原因
執行順序如下列註釋序號所示
//下面代碼輸出YXYZ的原因,和Java調用機制有關
class X{
//5.初始化動作總是先於構造函數執行,所以先執行類的初始化動作
//6.此處會調用類Y的構造函數
Y y=new Y();
public X(){
//3.此處隱藏了super()語句,所以調用直接父類Object的構造函數
//4.Object沒有父類,所以程序返回到此處.
//10.本類初始化完成,執行權回到此處,打印輸出X,程序返回
System.out.print("X");
}
}
class Y{
public Y(){
//7.此處隱藏了super()語句,所以調用直接父類Object的構造函數
//8.Object沒有父類,所以程序返回到此處.
//9.沒有成員變量需要初始化,所以繼續執行下面代碼,打印輸出Y,程序返回
//13.此處隱藏了super()語句,所以調用直接父類Object的構造函數
//14.Object沒有父類,所以程序返回到此處.
//15.沒有成員變量需要初始化,所以繼續執行下面代碼,打印輸出Y,程序返回
System.out.print("Y");
}
}
public class Z extends X{
//12.程序來到此處執行初始化動作,此處會調用類Y的構造函數
Y y=new Y();
public Z(){
//2.此處隱藏了super()語句,所以調用直接父類X的構造函數
//11.執行權回到此處,但本類成員變量尚未初始化,先初始化
//16.本類初始化完成,執行權回到此處,打印輸出Z,程序返回
System.out.print("Z");
}
public static void main(String[] args) {
//1.調用類Z的構造函數
new Z();
//17.程序執行到此處,結束。
}
}