我使用的是Java 7,有3个类:
TestSuper.java
public abstract class TestSuper {
public TestSuper() {
testMethod();
}
protected abstract void testMethod();
}
TestNull.java
public class TestNull extends TestSuper {
private String test = "Test";
public TestNull() {
super();
System.out.println(test);
}
@Override
protected void testMethod() {
System.out.println(test);
}
}
TestMain.java
public class TestMain {
public static void main(String[] args) {
new TestNull();
}
}
输出:
null
Test
为什么会发生这种情况,并且有很好的解决方法?
[当您调用new TestNull();
时,您正在调用类TestNull
的构造函数,它调用了super()
构造函数:它包含对在TestNull
中实现的方法的调用,您将在其中打印String字段,目前,子类TestNull
的字段尚未初始化,即为空。
在超级构造函数调用之后,所有字段都将被初始化,因此第二个打印实际上显示了(初始化的)字符串的新值。
这里的关键点是子类的字段已初始化after超类的实例化。
解决方法?这取决于您想要的确切行为:在超级构造函数中(即TestSuper
类的构造函数中)不调用abstract方法也许很有意义。
您正在调用构造函数中的overridable
您可以通过将testMethod()
的调用移至单独的函数来解决此问题,>
public abstract class TestSuper {
public TestSuper() { }
public void callTestMethod(){
testMethod();
}
protected abstract void testMethod();
}