我有这个代码,输出与预期不同。测试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
答案 0 :(得分:2)
您似乎希望您的代码等同于
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);
}
...
}
构造函数中的代码不会替换默认初始化;相反,初始化器在构造函数之前运行。
答案 1 :(得分:1)
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);
}
}
答案 2 :(得分:0)
您的问题为什么会这样?
因为每次初始化 Test2 时,都会初始化测试两次。因为每次加载一个类时,它都会加载其所有子类。因此,每当 Test2 类加载时,它都会加载并初始化构造函数外部和内部的测试。
这就是为什么你也得到构造函数1 。
答案 3 :(得分:0)
你得到那些输出,因为执行顺序如下:
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);