skip to content

How does an infinite loop like 'while (true)' affect reachability of the code that follows it?

level: middleimportance: should knowfreq 40%

answer

  1. while(true) + no break -> code after it unreachable (error)
  2. Rule keys on 'can complete normally'
  3. Constant true only; while(flag) is fine
  4. Infinite-loop method needs no return
  5. Add reachable break -> following code reachable -> return required

basics

~10 s

With 'while (true)' and no break, the loop never ends, so any statement written after it can never run. The compiler treats that following code as unreachable and reports a compile error.

solid answer

~40 s

A `while (true)` whose condition is the constant `true` and that contains no `break` (that targets it) never terminates normally. By the JLS rules, the statement *after* such a loop is unreachable, so writing code there is a compile error. This also has a useful consequence: a method whose body is an infinite loop does not need a `return` even if it declares a return type, because the end of the method is unreachable. The moment you add a reachable `break`, the loop can complete, so following code becomes reachable again and the compiler may then *require* a return. Note the analysis is about a *constant* `true` condition; `while (someBoolean)` where the value isn't a constant is treated as possibly terminating, so following code is reachable.

code

java · 6 lines
java
int loopForever() {
    while (true) {
        handle();
    }
    // no return needed: end of method is unreachable
}

go deeper

for a junior

Knows code after 'while(true)' won't compile and that such loops 'run forever'.

for a middle

States that the rule depends on a constant-true condition and the absence of a break, and that a following statement becomes an unreachable-code error.

for a senior

Connects it to the 'no return required' consequence and explains how adding a reachable break flips both reachability and the return requirement.

for a principal

Reasons precisely about 'completes normally' semantics, nested-loop/switch break targeting, constant vs. variable conditions, and how the same rule underpins definite-return analysis.

## The setup ```java while (true) { doWork(); } System.out.println("done"); // ERROR: unreachable statement ``` An **infinite loop** is a loop that never terminates on its own. `while (true)` with a constant-`true` condition and no `break` is the canonical example. Since control never leaves the loop, the `println` after it can **never** run — it is unreachable, and Java makes that a compile error. ## The relevant JLS rule The reachability rules say the statement following a `while` is reachable iff the `while` statement can *complete normally*. A `while (true)` with a constant-true condition can complete normally **only** if it contains a `break` statement that targets it. With no such `break`, it cannot complete normally → anything after it is unreachable. Key word: **constant**. The rule only fires when the condition is a constant expression equal to `true` (the literal `true`, or a `static final boolean` set to `true`). For `while (flag)` where `flag` is an ordinary variable, the compiler assumes the loop *might* end, so following code is reachable. ## The 'no return needed' consequence Because the end of an infinite-loop body is unreachable, a method can satisfy the 'must return a value' requirement *without* a return statement: ```java int serve() { while (true) { handle(); // never exits } // no return needed: the end of the method is unreachable } ``` This compiles. The compiler's 'every path must return' rule is itself phrased in terms of reachability: if the end of the method is unreachable, there's no path that falls off the end, so no return is required. Common in event loops, servers, and `main` loops. ## Add a break and everything changes ```java int serve() { while (true) { if (stop()) break; // loop CAN complete normally now handle(); } // reachable now -> compiler REQUIRES a return here return 0; } ``` Once a reachable `break` exists, the loop can complete normally, so the code after it (and the end of the method) becomes reachable — and now the compiler insists on a `return`. ## Pitfalls - A `break` inside a *nested* loop or `switch` that doesn't target the outer `while (true)` does NOT make the outer loop completable; the unreachability still holds. - `return` or `throw` inside the loop body lets the method end, but that's exiting the *method*, not completing the loop normally — code physically after the loop is still unreachable. - `for (;;) {}` is equivalent to `while (true) {}` (an omitted for-condition is treated as constant true), with the same effects.

  • Why can a method with an infinite loop and a non-void return type compile without a return statement?
    Because the end of the method is unreachable. The 'every path must return a value' rule is reachability-based: if no path can fall off the end, no return is needed.
  • Does 'while (running)' (running being a non-final boolean field) make following code unreachable?
    No. Only a constant-true condition triggers the rule. A variable condition is treated as possibly false, so the loop may terminate and following code is reachable.

saying these in an interview costs you the question

  • Thinking 'while (true)' always needs a return after it — it must NOT have reachable following code
  • Believing while(flag) with a non-constant variable triggers the rule
  • Assuming a break in a nested loop makes the outer infinite loop completable
  • Confusing return-in-body (exits method) with the loop completing normally

context