When there is some statement written after the infinite loop, that statement becomes the unreachable code. For ex:
for(;;)
{
}
Sytem.out.println(\"Test-1\")
The key phrase in http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21 is:
It is a compile-time error if a statement cannot be executed because it is unreachable.
This section is devoted to a precise explanation of the word "reachable." The idea is that there must be some possible execution path from the beginning of the constructor, method, instance initializer, or static initializer that contains the statement to the statement itself. The analysis takes into account the structure of statements. Except for the special treatment of while, do, and for statements whose condition expression has the constant value true, the values of expressions are not taken into account in the flow analysis.
Hence the compiler does not evaluate z<2 in your if() statement, and does not know
that it will never evaluate to true.
This defines unreachable code as far as the Java spec is concerned. It's important that compilers adhere to to the spec, because changing the rules could make code that used to compile fail to compile.
However, compilers are free to give warnings rather than compilation errors.
If I type the following code into Eclipse:
final int x = 0;
if(x == 1) {
System.out.println("This never happens");
}
... I get the warning "Dead code". The compiler knows the code can't be reached - but it can't refuse to compile, because the code is not formally "unreachable" according to the Java spec.