请原谅任何轻微的语法错误或诸如此类的问题,我正在使用 Jitsi 模块遇到这种情况,并且对 Java 不太熟悉,想确认发生了什么以及为什么以及如何修复它。
public abstract class A
{
public A()
{
this.load();
}
protected void load()
{
}
}
public class B extends A
{
private String testString = null;
public B()
{
super();
}
@Override
protected void load()
{
testString = "test";
}
}
应用程序在使用按名称加载类的方法创建类 B 的实例时执行此操作:
- 在 B 类中调用重写的 load()
- 初始化变量(根据调试器调用“private string testString = null”),将它们清空。
这是预期的 Java 行为吗?什么可能导致这种情况?它是在 1.7 JDK 上运行的 Java 1.6 应用程序。
最佳答案
Is this expected Java behavior?
是的。
What could cause this?
您在非最终父类(super class)构造函数中调用非最终覆盖方法。
让我们一步一步来看看会发生什么:
- 您创建一个
B
的实例。 B()
调用父类(super class)构造函数-A()
,初始化父类(super class)成员。A()
现在调用在B
类中被覆盖的非 final方法,作为初始化的一部分。- 由于上下文中的实例属于
B
类,所以调用的方法load()
属于B
类。 load()
初始化B
类实例字段 -testString
。- 父类(super class)构造器完成工作并返回(假设构造器链接到
Object
类已经完成) B()
构造函数开始进一步执行,初始化它自己的成员。- 现在,作为初始化过程的一部分,
B
会覆盖testString
中先前写入的值,并将其重新初始化为null
。
道德:永远不要在其构造函数中调用非最终类的非最终公共(public)方法。
关于java - 从构造函数调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18138397/