[英]Java: Initialization with class declaration
我有此代碼,並且輸出與預期的不同。 測試t1已經被覆蓋,但仍保持其初始值。 為什么會這樣呢?
public class Test2 {
Test t1 = new Test(1);
Test2(int i) {
t1 = new Test(i);
}
public static void main(String[] args) {
Test2 t2 = new Test2(5);
Test2 t3 = new Test2(15);
}
}
class Test {
Test(int x) {
System.out.println("Constructor called " + x);
}
}
輸出為:
Constructor called 1
Constructor called 5
Constructor called 1
Constructor called 15
您似乎希望您的代碼等同於
public class Test2 {
Test t1;
Test2(int i) {
t1 = new Test(i);
}
...
}
其實等於
public class Test2 {
Test t1;
Test2(int i) {
t1 = new Test(1);
t1 = new Test(i);
}
...
}
構造函數中的代碼不會替代默認初始化; 而是在構造函數之前運行初始化程序。
public class Test2 {
Test t1 = new Test(1); // you are creating Test class twice with argument 1 so output will be 1.
Test2(int i) {
t1 = new Test(i); // i = 5 and 15
}
public static void main(String[] args) {
Test2 t2 = new Test2(5); // Here you create 2 new instances so constructor called twice
Test2 t3 = new Test2(15);
}
}
class Test {
Test(int x) {
System.out.println("Constructor called " + x);
}
}
您的問題為什么會這樣?
因為每次您初始化Test2 ,它都會初始化兩次Test 。 因為每次加載類時,它都會加載其所有子級。 因此,每當Test2類加載時,它都會在構造函數的內部和外部加載並初始化Test 。
這就是為什么您也將構造函數稱為1的原因 。
之所以得到這些輸出,是因為執行順序如下:
class Test2{
Test t1 = new Test1(1); //Executed first
public Test2(int i){
t1 = new Test(i); //Executed second
}
}
您需要了解的下一件事是,當您使用new
關鍵字時,將調用構造函數。 因此,類Test1
的構造函數被調用4次:
public static void main(String[] args) {
Test2 t2 = new Test2(5); //Test1 constructor invoked twice here
Test2 t3 = new Test2(15); //Test1 constructor invoked twice here
}
運行Test2 t2 = new Test2(5);
將調用
new Test1(1); //from: Test t1 = new Test1(1);
new Test(5); //from: t1 = new Test(i);
運行Test2 t3 = new Test2(15);
將調用
new Test1(1); //from: Test t1 = new Test1(1);
new Test(15); //from: t1 = new Test(i);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.