10
class For1
{
  public static void main(String args[])
  {
    int a = 0;
    for(;;)
    {
      break;
      System.out.println(a); //Line 1
      ++a;//Line 2
    }
  }
}

我知道第 1 行/第 2 行永远不会被执行。但我仍然不明白为什么会抛出编译时错误。我收到“无法访问的语句”编译错误。

这是否意味着编译器会检查它是否能够编译所有分支/代码行?

4

6 回答 6

15

这是否意味着编译器会检查它是否能够编译所有分支/代码行?

这意味着编译器会检查每个语句是否可访问。

JLS 的第 14.21 节

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

本节专门对“可达”一词进行精确解释。这个想法是,从包含语句的构造函数、方法、实例初始化程序或静态初始化程序的开头到语句本身,必须有一些可能的执行路径。该分析考虑了语句的结构。

然后,该部分记录了可达性是如何定义的。

特别是,您的案例中的相关要点是:

如果 S 之前的语句可以正常完成,则非空块中不是 switch 块的所有其他语句 S 都是可访问的。

, break, continue, returnorthrow语句不能正常完成。

因此,您的“第 1 行”语句前面有一个无法break;正常完成的语句 ( ) ,因此无法访问。

于 2013-08-19T07:08:19.893 回答
7

编译器也能够得出这个结论,并假设您犯了一个错误。是的,Java 编译器做了相当多的“数据流分析”。最常见的相关消息是关于变量未初始化的消息。第二个最常见的是,我相信,正是这个,关于代码不可访问。

于 2013-08-19T07:07:53.597 回答
4

这是否意味着编译器会检查它是否能够编译所有分支/代码行?

是的,编译器会编译整个代码体并根据您的代码生成字节码,它unreachable code也足够聪明地检测到dead code. 立即breakfor-loop使其他语句无法访问。

for(;;){
   break;
   ... // unreachable statement
}


int i=1;
if(i==1)
  ...
else
  ... // dead code
于 2013-08-19T07:08:47.613 回答
3

无法访问的代码是无意义且多余的。如果您的程序中有一些无法访问的代码,这是一个错误,需要修复。因此编译器会抛出错误。

您可以参考下面的类似问题

无法访问的代码:错误还是警告?为什么 Java 会出现“无法访问的语句”编译器错误

于 2013-08-19T07:24:41.777 回答
2

编译器能够确定这两个语句永远不会被执行,并通过拒绝编译来帮助您编写正确的代码,因为这有 99.9% 的可能性是错误而不是有意识地选择添加永远不会执行的语句被执行。

于 2013-08-19T07:09:00.657 回答
1

编译器将检查某些关键字之后是否有更多代码。另一个会导致类似消息的关键字是如果您替换breakreturn.

于 2013-08-19T07:08:25.383 回答