-2

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

6
  • The compiler does not evaluate if (true), therefore it cannot know if the first one actually throws an exception. The second one either never ends or always throws an exception. The compiler can understand the while is entered but never properly exited. The try-catch is irrelevant in both cases, just throw a new and empty exception in both cases. Commented Aug 11, 2022 at 13:08
  • And what is the exact error message? Commented Aug 11, 2022 at 13:08
  • I didn't write code like this, i am preparing for Java OCP exam, therefore i test it all cases Commented Aug 11, 2022 at 13:12
  • Does this answer your question? Why is it not allowed to throw an exception in a Java instance initialization block? Commented Aug 11, 2022 at 13:18
  • I saw this answers, but i don't understand differences between while(true) and if(true) in this case Commented Aug 11, 2022 at 13:22

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @Andy Turner for your detailed answer, i don't have enough reputation, i really want to give your answer upvote, and one thing is this Oracle docs great resource for learning Java deeply or do you have other resources that you suggest highly?
@MammadYahyayev "learning" Java this deeply just for the sake of learning it makes very little sense unless you are actually trying wo write code that needs to know about / handle these kind of minute details. Most Java programmers have no idea of the difference, rightfully so because it is irrelevant in the day to day business. Working through the JLS and memorizing it will serve very little purpose.
@MammadYahyayev I agree with what luk2302 said. My knowledge of the JLS comes from need, insofar as I needed to understand select bits of the language deeply in order to write static analysis tools. If you want to be exposed to some of the odd foibles of Java, I would recommend Java Puzzlers: it's quite an old book, but it functions as quite an interesting tour through language design problems, with detailed explanations, but without the dryness of the language spec.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.