通过重写方法设置一个具有默认值的变量(例如本示例中的public boolean test = false;
),使该变量一旦到达构造函数,便被设置为默认值。但是,如果我将其更改为public boolean test;
,它将按预期运行。
public static void main(String[] args) {
/* False */
System.out.println(new Test2().test);
}
public static class Test {
public Test() {
this.test();
/* True */
System.out.println(((Test2) this).test);
}
public void test() {}
public static class Test2 extends Test {
public boolean test = false;
public Test2() {
/* False */
System.out.println(this.test);
}
@Override
public void test() {
this.test = true;
}
}
}
我想知道是什么原因导致这种现象,除了没有默认值之外,是否有其他办法可以防止它发生?
答案 0 :(得分:1)
在Java中,不带参数的基类的构造函数在派生类构造函数中自动调用。
在您的情况下,当您创建Test2类的实例时,Java首先调用基类的构造函数(Test的no参数构造函数),该构造函数从派生类中调用重写test()方法。
在构造过程中,构造函数将字段测试的Initializer的值设置为false,该构造器在构造函数中处理其他逻辑之前,但是在调用基类构造函数之后进行处理。
在代码的执行顺序下查找:
public static void main(String[] args) {
System.out.println(new Test2().test); // 6 - print false
}
public static class Test {
public Test() {
this.test(); // 1 - call the test method from derivative class
System.out.println(((Test2) this).test); // 3 - print true
}
public void test() {}
public static class Test2 extends Test {
public boolean test = false; // 4 - set the test field to false
public Test2() {
System.out.println(this.test); // 5 - print false
}
@Override
public void test() {
this.test = true; // 2 - set the test field to true
}
}
}