The compiler writers do not get to decide which conditions to flag as errors - the rules are in the Java Language Specification, for this issue in 14.21 Unreachable Statements.
The relevant sentence is: "The contained statement is reachable iff the while statement is reachable and the condition expression is not a constant expression whose value is false."
In each case, you have a reachable while statement. In the first version, false
is a constant expression whose value is false, so the contained statement is not considered reachable. In the second version, b
is not a constant expression at all, so the contained statement is treated as being reachable.
Adding final
to the declaration of b
changes the while condition to a constant expression whose value is false, making the contained statement unreachable again.
Specifying the rules for what is and is not a compile time error in the JLS has the benefit that all Java compilers should accept the same set of programs. The rules generally do not require the compiler to do data flow analysis, presumably to limit the cost and difficulty of writing compilers.