class X
{
Y b = new Y();// 【2】父類在調用構造函數之前會首先加載自己的成員變量,這裏打印第一個Y
X()
{
System.out.print("X"); //【3】調用父類構造函數,打印X
}
}
class Y
{
Y()
{
System.out.print("Y");
}
}
public class Test extends X {
Y y = new Y(); //【4】再加載本類的成員函數,因爲構造函數作用就是給成員初始化,這裏是第二個Y
Test()
{ //【1】首先從這裏開始走,這裏默認有一個super(),所以請跳轉到父類中
System.out.print("Z");//【5】這裏打印最後一個字母Z
}
public static void main(String[] args)
{
new Test();//【0】這裏是程序入口,調用了本類構造函數,請移步本類構造函數
}
}//最後打出來是YXYZ
/*
調用子類構造方法之後 執行順序如下:
父類static代碼塊(僅執行一次)--->子類靜態代碼塊(僅執行一次)
---->父類(父類成員隱式初始化--->父類成員顯式初始化--->父類構造代碼塊 --->父類構造方法)
---->子類(子類成員隱式初始化--->子類成員顯式初始化--->子類構造代碼塊 --->子類構造方法)
即new Test();構造了子類
先去構造父類 發現父類有顯式初始化 Y b=new Y(); ---->輸出Y
再執行父類構造函數 輸出X
此時回到子類 本想執行子類構造方法Test() 但是發現子類也有成員變量顯式初始化 Y y=new Y(); -->再次輸出Y
最夠進入子類Test的構造方法 --->輸出Z
*/
簡要點講就是 執行順序爲:
1靜態代碼塊2成員默認初始化
3成員顯示初始化
4構造代碼塊
5構造函數
其中 靜態代碼塊 只在加載類時運行一次 構造代碼塊 創建一次對象就運行一次
如果有父類,在創建子類對象時 須知道父類是怎麼樣的,所以需要先加載父類 順序如上
加載完父類以後 在加載子類 順序如上
-------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ----------------------