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

Why the first code snippet fails to compile (with compile error "Initializer does not complete normally") while the second compiles fine? The only difference is in the way how the exception is thrown!

class CompilationFailsClass {   

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

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

vs

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.

Jon Skeet
people
quotationmark

The JLS is pretty clear about this, in section 8.6:

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

In your first example, the instance initializer can't complete normally.

In the second example, as far as the compiler's concerned it can complete normally. It never will, but the compiler doesn't know that, therefore it's fine.

people

See more on this question at Stackoverflow