Infinite loops & unreachable code in Java
while(true), compiler unreachable-statement errors.
Forever, on purpose
while (true) (or for (;;)) loops forever unless a break, return or exception gets out. That's not a bug: game loops, servers and input loops all work this way, with an exit inside.
while (true) {
String cmd = readCommand();
if (cmd.equals("quit")) break;
run(cmd);
}
System.out.println("bye");Your turn
What prints?
int n = 3;
while (true) {
n = n * 3;
if (n > 50) break;
}
System.out.println(n);278150Compile error
Show the answer
n triples: 9, 27, 81. Only at 81 is n > 50, so break exits and 81 prints. The println is reachable because the loop contains a break.
The compiler does the math
If a while (true) has no break, it can never finish normally, so any statement after it can never run. Java makes that a compile error: unreachable statement. The check works with constants like true; the compiler doesn't evaluate your variables.
int x = 0;
while (true) {
x++;
}
System.out.println(x); // unreachableYour turn
What happens?
for (;;) {
System.out.println("tick");
}
System.out.println("done");Prints tick foreverCompile errorPrints done
Show the answer
Compile error. for (;;) has no condition and the body has no break, so the compiler proves done can never print, and rejects the program before it ever runs.
Dead code after a jump
A statement placed directly after return, break or continue in the same block can never run. That's also an unreachable statement compile error.
for (int i = 0; i < 3; i++) {
continue;
System.out.println(i); // error
}A curious exception
if (false) { ... } compiles fine, but while (false) { ... } doesn't. Why the difference?
Think about it, then reveal the answer
The language spec special-cases if so you can switch code off with a constant flag like if (DEBUG). A loop whose condition is the constant false has an unreachable body, which is an error. Same for for (;false;).
In real projects
Event loops in servers, games and GUI frameworks are while (true) loops at heart, each with a clear exit. The unreachable-statement check also earns its keep during refactoring: it flags leftover code after an early return that someone forgot to delete.
Key takeaways
- while (true) { ... if (done) break; } is a normal, legal pattern
- A statement after an infinite loop with no break doesn't compile
- Code directly after return, break or continue in the same block is unreachable
- if (false) { ... } is allowed on purpose; while (false) { ... } is not
In 1936 Alan Turing proved that no program can decide, for every program, whether it will halt. That's why javac only checks simple cases like while (true) and can't catch every infinite loop.
Practice questions
What does this print?
int n = 1;
while (true) {
n *= 2;
if (n > 20) break;
}
System.out.println(n);- 16
- 32
- 20
- Compile error
Check your answer
32. n doubles: 2, 4, 8, 16, 32. Only at 32 is n > 20, so break exits and 32 prints. The println is reachable thanks to the break.
What does this print?
int x = 0;
while (true) {
x++;
}
System.out.println(x);- Prints 0
- Compile error
- Runs forever, prints nothing
- Throws StackOverflowError
Check your answer
Compile error. The loop has no break, so the compiler knows it can never finish normally. The println after it is an unreachable statement.