Java:使用类声明进行初始化

时间:2017-10-29 12:00:30

标签: java

我有这个代码,输出与预期不同。测试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

4 个答案:

答案 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);