-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

  • 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. – luk2302 Aug 11 '22 at 13:08
  • And what is the exact error message? – Chaosfire Aug 11 '22 at 13:08
  • I didn't write code like this, i am preparing for Java OCP exam, therefore i test it all cases – Mammad Yahyayev Aug 11 '22 at 13:12
  • Does this answer your question? [Why is it not allowed to throw an exception in a Java instance initialization block?](https://stackoverflow.com/questions/13532794/why-is-it-not-allowed-to-throw-an-exception-in-a-java-instance-initialization-bl) – Rishal Aug 11 '22 at 13:18
  • I saw this answers, but i don't understand differences between `while(true)` and `if(true)` in this case – Mammad Yahyayev Aug 11 '22 at 13:22
  • @luk2302 i understand your answer, and i have a request, where you learn this, i mean can you share any resource – Mammad Yahyayev Aug 11 '22 at 13:30

1 Answers1

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.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 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? – Mammad Yahyayev Aug 11 '22 at 13:49
  • @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. – luk2302 Aug 12 '22 at 06:24
  • @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. – Andy Turner Aug 15 '22 at 13:40