Java中何时出现"无法访问的代码"?

Vik*_*gal 5 java unreachable-code

当在无限循环之后写入某些语句时,该语句将成为无法访问的代码.例如:

for(;;) 
{
}
Sytem.out.println("Test-1"); //unreachable code
Run Code Online (Sandbox Code Playgroud)

但我在这里面临一些困难.

请看下面的两个代码段:

代码片段1:

for(final int z=4;z<6;)
{
}
System.out.println("Test-2"); //unreachable code
Run Code Online (Sandbox Code Playgroud)

这里,最后一个语句必须是不可达的,因为循环是无限的,输出是预期的.

代码片段2:

final int z=4;
for(;;)
{
    if(z<2)
        break;
}
System.out.println("Test-3");  //not unreachable
Run Code Online (Sandbox Code Playgroud)

从概念上讲,上面代码中的for循环也是无限的,因为z是final,并且if(z<2)仅在编译时确定.if条件永远不会为真且循环永远不会中断.但是,上面代码中的Last语句是无法访问的.

问题:

  1. 为什么会这样?

  2. 任何人都可以告诉我确切的规则,我们可以看到代码是否无法访问.

sli*_*lim 3

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21中的关键短语是:

如果某个语句由于无法访问而无法执行,则这是一个编译时错误。

本节专门对“可达”一词进行精确解释。这个想法是,从包含语句的构造函数、方法、实例初始值设定项或静态初始值设定项的开头到语句本身,必须存在一些可能的执行路径。分析考虑了陈述的结构。除了对条件表达式为常量true的while、do、for语句进行特殊处理外,在流分析中不考虑表达式的值。

因此,编译器不会z<2在您的if()语句中进行计算,并且不知道它永远不会计算为true.

就 Java 规范而言,这定义了不可访问的代码。编译器遵守规范非常重要,因为更改规则可能会使用于编译的代码无法编译。

然而,编译器可以自由地给出警告而不是编译错误。

如果我在 Eclipse 中输入以下代码:

final int x = 0;
if(x == 1) {
    System.out.println("This never happens");
}
Run Code Online (Sandbox Code Playgroud)

...我收到警告“死代码”。编译器知道代码无法访问 - 但它不能拒绝编译,因为根据 Java 规范,代码并不是正式的“无法访问”。