根据Java Language Spec ,无法访问代码是一个错误。
引用 JLS 的话:
这个想法是,从包含语句的构造函数、方法、实例初始化程序或静态初始化程序的开头到语句本身,必须有一些可能的执行路径。该分析考虑了语句的结构。除了特殊处理while、do和条件表达式为真值的语句外,流分析中不考虑表达式的值。
这意味着,if
没有考虑该块,因为如果您通过if
语句的路径之一,您可以到达最终的打印语句。如果您将代码更改为:
public void foo() {
System.out.println("Hello");
if (true)
return;
else
return;
System.out.println("World!");
}
然后突然它不再编译了,因为没有通过if
语句的路径可以到达最后一行。
也就是说,Java 兼容的编译器不允许编译您的第一个代码片段。进一步引用 JLS:
例如,以下语句会导致编译时错误:
while (false) { x=3; }
因为语句 x=3; 无法到达;但表面上类似的情况:
if (false) { x=3; }
不会导致编译时错误。优化编译器可能会意识到语句 x=3; 将永远不会被执行,并且可以选择从生成的类文件中省略该语句的代码,但是语句 x=3; 在此处指定的技术意义上,不被视为“无法访问”。
Eclipse 给出的关于死代码的第二个警告是编译器生成的警告,根据 JLS,这不是“无法访问”,但实际上是。这是 Eclipse 提供的附加lint样式检查。这完全是可选的,并且通过使用 Eclipse 配置,可以禁用,或者变成编译器错误而不是警告。
第二个块是“代码气味”,if (false)
通常会放入块以禁用代码以进行调试,将其留在后面通常是偶然的,因此会发出警告。
事实上,Eclipse 进行了更高级的测试来确定 if 语句的可能值,以确定是否可以采用两条路径。例如,Eclipse 也会在以下方法中抱怨死代码:
public void foo() {
System.out.println("Hello");
boolean bool = Random.nextBoolean();
if (bool)
return;
if (bool || Random.nextBoolean())
System.out.println("World!");
}
它将为第二个 if 语句生成一个无法访问的代码,因为它可以推断该代码bool
必须仅false
在代码中的这一点上。在如此短的代码片段中,很明显两个 if 语句正在测试相同的东西,但是如果中间有 10-15 行代码,它可能不再那么明显了。
综上所述,两者的区别是:一种是被 JLS 禁止的,一种是不被 JLS 禁止的,而是被 Eclipse 检测为为程序员提供的服务。