Inaccessible code is a bug according to the Java Language Spec .
Quote from JLS:
The idea is that there should be some possible execution path from the beginning of the constructor, method, instance initializer, or static initializer that contains the instruction to the statement itself. The analysis takes into account the structure of statements. Except for special processing while, do, and for statements whose condition expression has a constant value true, the values of the expressions are not taken into account when analyzing the flow.
What this means is that the if block if not taken into account, because if you go through one of the paths of the if , you can get the final print statement. If you changed your code:
public void foo() { System.out.println("Hello"); if (true) return; else return; System.out.println("World!"); }
then all of a sudden it will no longer compile, because there is no path in the if to reach the last line.
That is, a Java-compatible compiler cannot compile your first piece of code. To optionally specify JLS:
As an example, the following statement results in a compile-time error:
while (false) { x=3; }
because the statement x = 3; not available; but an outwardly similar case:
if (false) { x=3; }
does not result in a compile-time error. The optimizing compiler can understand that the operator x = 3; will never be executed and may omit the code for this statement from the file of the generated class, but statement x = 3; not considered as “unreachable” in the technical sense indicated here.
The second warning that Eclipse gives, about dead code, is a warning generated by the compiler that is not "inaccessible" according to JLS, but in practice it is. This is an additional lint check that Eclipse provides. This is completely optional, and using the Eclipse configuration, you can disable or turn it into a compiler error instead of a warning.
This second block is a "code smell", usually block if (false) blocks to disable the code for debugging purposes, leaving it, as a rule, random and, therefore, a warning.
In fact, Eclipse performs even more complex tests to determine the possible values for the if statement, to determine if both paths can be taken. For example, Eclipse will also complain about dead code in the following way:
public void foo() { System.out.println("Hello"); boolean bool = Random.nextBoolean(); if (bool) return; if (bool || Random.nextBoolean()) System.out.println("World!"); }
It will generate unreachable code for the second if statement, since it can justify that bool should only be false at this point in the code. In such a short piece of code, it is obvious that two if statements test the same thing, however, if there are 10-15 lines of code in the middle, this may not be so obvious.
Thus, the difference between the two: one is prohibited by JLS and the other is not, but Eclipse is detected as a service for the programmer.