[英]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.