java中具備繼承關係的類及其對象初始化順序

先說結論
對於具備繼承關係的類,它們的類和對象構造順序爲:父類的類構造器() -> 子類的類構造器() -> 父類成員變量的賦值和實例代碼塊 -> 父類的構造函數 -> 子類成員變量的賦值和實例代碼塊 -> 子類的構造函數。函數

實驗代碼以下:code

public class ExtensionTest {

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

class SuperClass
{
    {
        System.out.println("我是父類實例塊");
    }
    static {
        System.out.println("我是父類類構造塊");
    }
    public SuperClass()
    {
        System.out.println("我是父類構造函數塊");
    }
}
class SubClass extends SuperClass
{
    {
        System.out.println("我是子類實例塊");
    }
    static {
        System.out.println("我是子類類構造塊");
    }
    public SubClass()
    {
        System.out.println("我是子類構造函數塊");
    }

}

結果:對象

我是父類類構造塊
我是子類類構造塊
我是父類實例塊
我是父類構造函數塊
我是子類實例塊
我是子類構造函數塊繼承

解釋:
類構造塊是初始化類的時候執行的,而初始化類首先得加載類(不加載類進內存固然無法初始化)。
類實例塊是放在該類構造函數最前面和父類構造函數以後執行的。由於子類的構造函數調用以前,會先調用父類的構造函數。內存

基於上述兩條規則,咱們再來看執行順序。
new SubClass()也就是要構造SubClass這個類的一個對象,而要構造這個對象,首先必須把這個類的描述、定義加載進內存(類加載)。所以要先加載這個類(不過此時還未初始化)。
加載完這個類以後,想要構造這個類的對象。可是此時這個類的靜態變量還未被初始化,所以要先初始化這個類,可是初始化這個類須要先初始化它的父類,所以此時就變成了,加載父類->初始化父類(調用靜態塊,即類構造塊)
->初始化子類(調用靜態塊,即類構造塊)。
而後就能夠構造這個類的對象了,構造這個類的對象以前,要先構造父類對象,所以會先調用父類的構造函數,而調用父類構造函數以前又會先調用父類的實例塊。
而後就到了子類構造函數,然而執行以前同樣要先調用子類的實例塊,最後纔是子類的構造函數的函數體。io

相關文章
相關標籤/搜索