java - 为什么默认值会覆盖已通过覆盖方法设置的值
问题描述
设置一个具有默认值的变量,就像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;
}
}
}
我想知道是什么原因导致了这种行为,除了没有默认值之外,您是否可以采取任何措施来防止这种行为?
解决方案
在 Java 中,没有参数的基类构造函数在派生类构造函数中自动调用。
在您的情况下,当您创建 Test2 类的实例时,Java 首先调用基类的构造函数(Test 的无参数构造函数),该构造函数从派生类调用覆盖 test() 方法。
字段 test 的初始值设定项在构造期间处理,就在构造函数中的任何其他逻辑之前,但在调用基类构造函数之后。
在下面找到代码的执行顺序:
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
}
}
}
推荐阅读
- angular - 如何使用离子角度将图像上传到谷歌驱动器
- owin - 如何使用 OWIN 为多个 ADFS 端点设置通用 Wreply?
- java - @Configuration 在方法设置中需要获取参数“{browser}”,但尚未标记为 @Optional 或已定义(尝试过的解决方案)
- machine-learning - 线性回归系数与决策树特征重要性之间的关系
- css - 强制 Flexbox 在特定项目之后换行(方向:列)
- excel - vba 返回带问号的文件名,所以我无法重命名文件。如何获得真实的文件名?
- html - 如何按它们所在的区域命名树枝文件?
- bash - 为什么 awk 命令在 shell 脚本中不起作用
- android - 未解决的参考:Android Studio 3.4 中的 Observable
- android - 使用 android gradle 插件 3.4.0 定义 Checkstyle 任务