java - 通过声明初始化类 DS 字段 - 在构造函数调用之前还是之后?

标签 java oop initialization

在处理公司的遗留代码时,我在运行时遇到了 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 和从 PreConcreteClass 调用 super 后,调用 ConcreteClass 的重写更新方法时,会引发 NPE。原因是internalDS - 它为空,导致for循环抛出NPE。

首先 - 这与我一直期望的相反 - 在声明时初始化的类字段在执行构造函数的范围之前初始化。通过 super 调用派生类的构造函数时不是这样吗?

第二 - 我通过添加一个由 AbstractClass 构造函数调用的 init 方法解决了 NPE,该方法由 AbstractClass 给出了一个空实现,并被 ConcreteClass 通过内部 DS 上的初始化覆盖。

我查阅了一些一般建议in stack overflow 。 我在工作中与同事进行了一些讨论,我们一致认为上述设计存在继承问题,导致了 NPE。 由于这是我们不想彻底更改的遗留代码,因此我想知道是否有人有更好的替代方案来替代我使用的 init 方法解决方案。 注意 - 每个类都有多个构造函数。

最佳答案

不,编译器在调用 super 之后移动构造函数中的那些初始值设定项,因此您的代码等效于:

public class ConcreteClass extends PreConcreteClass{
   private List<Object> internalDS;
   public ConcreteClass() {
      super();
      internalDS = new ArrayList<>();
      ...
   }
   @Override
   protected void update() {
      ....
      for(Object o : internalDS) {
         ...
      }
      ...
}

请注意,有一条通用规则可以以更简洁的方式避免这种情况:永远不要在构造函数中调用非 final方法。它会把事情搞砸。

关于java - 通过声明初始化类 DS 字段 - 在构造函数调用之前还是之后?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48961601/

相关文章:

c# - 帮助 c# 模式

c - 在函数C编程中初始化多个数组

python - 在Python中的对象初始化中将self传递给函数

c++ - 为什么不认为类在静态数据成员初始值设定项中已完全定义?

java - LibGDX - 每当我的主角接触硬币时,IllegalArgumentException 都会导致我的游戏崩溃

java - Java 中完全弃用匿名线程?

java - 使用 Grails Webflow Controller 的方法或闭包?

java - 如何在启动 MainActivity 时直接选择 fragment 类?

sql - 面向对象的程序员如何了解数据库驱动的编程?

c++ - 没有初始化类的引用变量没有报错