在处理公司的旧代码时,我在运行时遇到了NPE。调试后,这就是我遇到的:
public class ConcreteClass extends PreConcreteClass{
private List<Object> internalDS = new ArrayList<>();
public ConcreteClass() {
super();
....
}
@Override
protected void update() {
....
for(Object o : internalDS) {
...
}
...
}
public class PreConcreteClass extends AbstractClass{
......
public PreConcreteClass() {
super();
......
}
......
}
protected abstract class AbstractClass {
protected AbstractClass() {
.....
update();
....
}
protected void update() {
.....
}
}
在调用Concreteclass的Super和Prodonconconcreteclass的Super后,将NPE抛出。原因是内部的 - 无效,导致for循环扔出NPE。
首先 - 这违背了我一直期望的 - 在执行构造函数范围之前,先初始化了在声明中初始化的类字段。通过超级?
second-我通过添加一个INIT方法来解决NPE,该方法由AbstractClass构造器调用,该方法由AbstractClass赋予了空的实现,并被ConcreteClass覆盖,并在Internalds上进行了初始化。
。我查找了堆栈溢出中的一些一般建议。我在工作中与同事进行了一些讨论,我们同意上面的设计有一个继承的问题,导致NPE。由于这是我们不想大幅更改的旧代码,因此我知道是否有人可以更好地替代我使用的Init方法解决方案。注意 - 每个类都有多个构造函数。
no,编译器在调用超级后正在构造函数中移动这些初始化器,因此您的代码等同于此:
public class ConcreteClass extends PreConcreteClass{
private List<Object> internalDS;
public ConcreteClass() {
super();
internalDS = new ArrayList<>();
...
}
@Override
protected void update() {
....
for(Object o : internalDS) {
...
}
...
}
请注意,有一个通用规则可以以更干净的方式避免这种情况:从不在构造函数中调用非最终方法。它会搞砸了。