javaexceptioninitializer

Instance Initializer Exception Handling


I didn't understand the difference between these codes. One of them is compiled, the other one isn't.

{
    if (true) {
        try {
            throw new IOException();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

This is a instance initializer, i throw a checked exception and then handle it, and this code compile.

But this one isn't compile.

{
    while (true) {
        try {
            throw new IOException();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Exception says: Initializer must be able to complete normally

Here is the image of both Instance Initializer


Solution

  • Stripping down your examples - because the try/catch/rethrow doesn't matter here:

    {
        if (true) {
            throw new RuntimeException();
        }
    }
    

    vs

    {
        while (true) {
            throw new RuntimeException();
        }
    }
    

    What matters here is whether Java considers that the statements can complete normally, because JLS 8.6 says:

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

    Consult the rules on unreachable statements:

    • An if-then statement can complete normally iff it is reachable.
    • ...
    • A while statement can complete normally iff at least one of the following is true:
      • The while statement is reachable and the condition expression is not a constant expression (§15.29) with value true.
      • There is a reachable break statement that exits the while statement.

    (You can also read this same section to find out why I say the try/catch/rethrow didn't matter).

    Notice that if doesn't have the same conditions on normal completion as while.