根据 Java 语言规范,无法访问的代码是一个错误。
引用JLS的话:
这个想法是,从构造函数,方法,实例初始值设定项或包含语句的静态初始值设定项的开头到语句本身,必须存在一些可能的执行路径。分析考虑了报表的结构。除了对 while、do 和条件表达式具有常量值 true 的语句的特殊处理外,在流分析中不考虑表达式的值。
这意味着不考虑块,因为如果您通过语句的其中一个路径,则可以到达最终的打印语句。如果您将代码更改为: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 语句生成一个无法访问的代码,因为它可以推理该代码中必须仅在此时。在如此短的代码片段中,很明显,两个if语句正在测试相同的内容,但是如果中间有10-15个代码行,它可能不再那么明显了。bool
false
因此,总而言之,两者之间的区别:一个是JLS禁止的,一个不是,而是被Eclipse检测为程序员的服务。