为什么编译取决于实例初始化程序中如何抛出异常?

Why compilation depends on how exception is thrown within instance initializer?

为什么第一个代码片段编译失败(编译错误"Initializer does not complete normally")而第二个代码片段编译正常?唯一的区别在于抛出异常的方式!

class CompilationFailsClass {   

   {
      // c.ERR Initializer does not complete normally
      throw new IOException();   
   }

   public CompilationFailsClass() throws IOException {
        // constructor
   }
}

class CompilationOKClass {

   // with empty body effect is exactly same
   static void f() throws IOException { throw new IOException(); }

   {
      f(); // OK !
   }

   public CompilationOKClass() throws IOException {
   }
}

JLS §11.2.3:

It is a compile-time error if an instance variable initializer (§8.3.2) or instance initializer (§8.6) of a named class can throw a checked exception class, unless the named class has at least one explicitly declared constructor and the exception class or one of its superclasses is explicitly declared in the throws clause of each constructor.

JLS 在 section 8.6:

中对此非常清楚

It is a compile-time error if an instance initializer cannot complete normally (§14.21).

在您的第一个示例中,实例初始化程序无法正常完成。

在第二个例子中,就编译器而言它可以正常完成。它永远不会 ,但编译器不知道,因此没关系。