我的一个类继承 self 使用的框架中的一个类。父类(super class)在其构造函数中调用一个方法,我在自己的类中覆盖了该方法。 该方法使用了一个字段,我想在它被 super 构造函数调用之前 初始化以避免 NullPointerException。
有什么办法吗?
这是一个综合测试场景,我希望 Child
中的 c
在调用 call
时不为 null。
public class Test {
public static class Parent {
public Parent() {
super();
call();
}
// only called from parent constructor
public void call() {
System.out.println("Parent");
}
}
public static class Child extends Parent {
private Child c = this;
public Child() {
super();
}
// only called from parent constructor
public void call() {
System.out.println("Child, c is " + (c == null ? "null" : "this"));
}
}
public static void main(String[] args) {
new Child();
}
}
在 Java 7 之前,这是可能的。我可以通过这样的特技来度过难关:
public static class Child extends Parent {
private Child c;
private Child(Object unused) {
super();
}
public Child() {
this(c = this);
}
// only called from parent constructor
public void call() {
System.out.println("Child, c is " + (c == null ? "null" : "this"));
}
}
现在,这不再有效了。我很欣赏额外的安全性,但是 super 的调用破坏了它获得的任何安全性并降低了灵 active 。
我想要一种规避此限制的方法。 作为替代方案,我想知道避免 super 构造函数情况的限制会带来什么。
最佳答案
静态初始化器将在父类(super class)构造函数之前被调用。但是,您将无法设置任何非静态字段,因此它很可能无济于事。
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
非静态初始化 block 也无济于事,因为它是在父类(super class)构造函数完成后调用的。
另一种方法可能是在从 super 构造函数调用时什么也不做,然后再次调用子构造函数,例如:
public Child() {
super();
call();
}
public void call() {
if (c==null) {
return;
}
System.out.println("do something with c now");
}
如果在依赖于此方法的 super 构造函数中发生更多事情,这将不起作用。
我必须同意 EJP 的观点,这是个坏主意;找到一个不涉及折磨构造函数的完全不同的解决方案会好得多。
关于java - 为什么必须在访问字段之前调用 super 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20347704/