为什么我没有收到这个问题的警告?

3 java ide syntax

假设我按以下方式定义了两个类:

public class A {

   public A() {
      foo();
   }

   public void foo() {
      System.out.println("A");
   }
}

public class B extends A {

   private String bar;

   public B() {
      bar = "bar";
   }

   @Override
   public void foo() {
      System.out.println(bar);
   }

}
Run Code Online (Sandbox Code Playgroud)

然后我通过以下方式实例化B:

A test = new B();
Run Code Online (Sandbox Code Playgroud)

那么为什么编译器分别不能让IDE警告我在B的foo方法中会有一个NullPointer?这不是很难检查,有时非常有用.

pol*_*nts 7

虽然这是设计错误,但这不是语法错误.

以下是Effective Java 2nd Edition,第17项:设计和继承文档的引用,或者禁止它:

为了允许继承,类必须遵守一些限制.构造函数不得直接或间接调用可覆盖的方法.如果违反此规则,将导致程序失败.超类构造函数在子类构造函数之前运行,因此在子类构造函数运行之前将调用子类中的重写方法.如果重写方法依赖于子类构造函数执行的任何初始化,则该方法将不会按预期运行.

一个听话的编译器会让它编译得很好,因为它在语言上是合法的.幸运的是,代码分析工具可用于查找这些设计错误,例如findbugs:

UR:从超类的构造函数调用的字段方法的未初始化读取(UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR)

在超类的构造函数中调用此方法.此时,该类的字段尚未初始化.