[英]Please explain this behaviour in java
class abc extends TestStart{
static{
System.out.println("c");
}
{
System.out.println("f");
}
public abc(){
System.out.println("d");
}
}
public class TestStart {
static {
System.out.println("A");
}
{
System.out.println("z");
}
public TestStart(){
System.out.println("b");
}
public static void main(String[] args) {
TestStart x = new abc();
TestStart y = new TestStart();
}
}
輸出-----------> czbfdzb
我認為此---- >>>>> TestStart的輸出行為x = new abc(); - - - - 應該 :-
我應該得到以下輸出:cfzbdzb
如果在父類和子類中沒有init塊,則此行為很大程度上是從此派生的。 請解釋我提到的輸出。
您得到了: A
c
z
b
f
d
z
b
而您卻期望: A
c
f
z
b
d
z
b
因此,您說的是您希望f
在z
b
之前發生。
因此,您實際上要說的是您期望的:
f
)的實例初始化器 在之前被調用
z
)和 b
)的構造函數。 好吧,這根本不是事情發生的方式。 基類的所有實例初始化必須在派生類的實例初始化開始之前完成,否則派生類將能夠訪問基類的未初始化成員。
並且所有靜態初始化內容( A
, c
)都是在問題中引發的紅色鯡魚,使我們感到困惑。
初始化后,所有類中的靜態塊和變量都會運行parent的初始化程序。 在父構造函數之后,然后是子構造函數中的子構造函數。 這是因為您可以在子初始化程序中使用某些父字段,因此必須在初始化之前對其進行初始化。
首先,命名:
public class TestStart {
static { // static initializer
System.out.println("A");
}
{ // instance initializer
System.out.println("z");
}
public TestStart() { // constructor
System.out.println("b");
}
}
沒錯,首先會調用靜態初始值設定項,但您唯一的保證就是在任何上下文中使用該類之前都要先調用類靜態初始值設定項。
對於實例初始化程序和構造函數,從第一次調用到最后一次調用的調用順序如下:
Parent initializer, Parent Constructor, Your Initializer, Your Constructor
如果您使用this()
從同一個類中調用其他構造函數,則在類中所有構造函數調用之前,都會調用一次初始化器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.