簡體   English   中英

在 java 中何時以及如何調用超級構造函數

[英]When and how super constructor is called in java

我試圖了解在鏈式構造函數中使用this()super()的構造函數的執行順序。 我嘗試了以下代碼:

public class ConstructorChaining{

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

class CCA
{
    public CCA() {
        this("");
        System.out.println("Inside A()");
    }

    public CCA(String a) {
        System.out.println("Inside A(String)");
    }
}

class CCB extends CCA 
{
    public CCB() {
        this("");
        System.out.println("Inside B()");
    }

    public CCB(String a) {
        //this(2);
        System.out.println("Inside B(String)");
    }

    public CCB(int a) {
        System.out.println("Inside B(int)");
    }
}

class CCC extends CCB 
{
    public CCC() {
        this("");
        System.out.println("Inside C()");
    }

    public CCC(String a) {
        this(5);
        System.out.println("Inside C(String)");
    }

    public CCC(int a) {
        System.out.println("Inside C(int)");
    }
}

這將打印以下內容:

Inside A(String)
Inside A()
Inside B(String)
Inside B()
Inside C(int)
Inside C(String)
Inside C()

所以我覺得:

如果沒有 class 的構造函數重載顯式調用super() ,則將執行其所有鏈式構造函數重載,然后隱式調用super() ,這又遵循相同的模式。

換句話說,在執行子 class 的所有鏈式構造函數重載后,最后對父級的默認構造函數進行隱式調用。 圖解地,

CO1() --this()--> CO2() --this()--> ... --this()--> COn              Constructor Overloads (CO) of Class Cn 
                                                     |
                                             Implicit super() call
                                                     |
                                                     v
COn() <--this()-- ... <--this()-- CO2() <--this()-- CO1              Constructor Overloads (CO) of Class Cn-1 which Cn's parent
 |
Implicit super() call
 |
 v
 :
 |
Implicit super() call
 |
 v    
CO1() --this()--> CO2() --this()--> ... --this()--> COn              Constructor Overloads (CO) of Class C1 which is C2's parent

如果我的觀察是正確的,那么我的疑問是,在當前 class 的所有鏈式構造函數都被執行之后,誰來決定何時隱式調用super() 另外,這個決定/行為是如何在 jdk / jre 中實現的? 編譯器是否在最后一次調用super()時生成字節碼,或者運行時動態決定調用super()

如果沒有 class 的構造函數重載顯式調用 super(),則將執行其所有鏈式構造函數重載,然后隱式調用 super(),這又遵循相同的模式。

不正確。

如果構造函數不是以this(...)super(...)開頭,那么編譯器會插入一個隱式的無參數super() 這絕不依賴於重載。

而已。 真的就是這么簡單。 最終調用超級構造函數不需要整體邏輯。

這正是您的圖表所顯示的。 調用super()的是構造函數COn ,因為編譯器添加了它。 如果調用的所有構造函數都有this(...)super(...) ,那么永遠不會調用無參數super()

是的? JVM 做了很多這樣的事情? 您可能想知道為什么 JVM 會這樣做,真的有必要嗎,好吧:要找出原因,請考慮以下代碼:

class A{
    int a;
    A(int value){ 
        a = value
    }
}

class B extends A{
    int b;
    B(int value){
        b = value;
    }
}

如果你編譯這段代碼,你會得到一個編譯錯誤說:“A 中沒有可用的默認構造函數” 那是因為 JVM 不知道給a什么值。 你可能會說int的默認值是 0,但是如果A有一個 object 字段並且在使用之前必須在構造函數中初始化呢? 因此,JVM 強制您在第一行調用晚餐類的構造函數,或者它隱式調用默認構造函數(如果沒有默認構造函數則拋出錯誤)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM