【问题标题】:Unreachable statement error using while loop in java [duplicate]在java中使用while循环无法访问语句错误[重复]
【发布时间】:2012-12-09 16:05:51
【问题描述】:

可能重复:
Why is this code giving an “Unreachable Statement” error?

这似乎很简单的问题,我在一本书中找到了这个问题。如果有人帮我弄清楚为什么我会出错。

    do {
        System.out.print("inside do");
    } while (false);
    while (false) { // error
        System.out.print("inside while");
    }
    System.out.print("outside");

我想,根据我的说法,输出应该在 doutside 内。但是,它显示 Compiler Error : Unreachable Statement。然后,我试图弄清楚,为什么,它显示 Compilation error : Unreachable Statement* 。所以,我把上面的代码改成这样

  boolean i = false;  
  do {
        System.out.print("inside do");
    } while (false);
    while (i) { // ok
        System.out.print("inside while");
    }
    System.out.print("outside");

现在,它显示了预期的输出,即 inside dooutside 。所以,我的问题是 - 第一种和第二种情况有什么区别? 另外,当我检查

if(false){ 
  //something here
   }

然后,上面的代码执行没有任何错误。

【问题讨论】:

    标签: java if-statement while-loop control-flow unreachable-statement


    【解决方案1】:

    前两个例子的主要区别在于,在第一种情况下,条件是常数,而在第二种情况下则不是。

    例如,如果您将boolean i = false; 更改为final boolean i = false;,您将得到相同的编译错误,因为 i 现在是一个常量。

    不可达语句的规则在JLS 14.21 中定义。特别是对if 进行了特殊处理,以允许if(DEBUG) 结构,其中DEBUG 可能是一个常量。

    至于do / while,里面的语句会执行一次,所以没有问题。

    有关this related post 中的常量的更多详细信息。

    【讨论】:

    • 但是,问题是为什么,我的意思是关于 while loop 的 AFAIK 没有必要执行该块。那么,为什么unreachable block error。即使,如果你看到我关于if 声明的第三个场景。在这种情况下,它会执行。
    • 所以,这意味着在if语句的情况下,编译器将省略该语句。这就是为什么,在if 的情况下它不会显示任何错误,不是吗??
    • @coders 它没有省略语句,但是在 if 的情况下,即使编译器确定 if 的主体永远不会被执行,也不会发出错误。跨度>
    【解决方案2】:

    编译器给你一个Unreachable statement错误,因为你的System.out.print("inside while");代码永远无法到达

    while (false) { // error
        System.out.print("inside while");
    }
    

    编译器知道while (false)永远不会为真,并警告您(有错误)有关死代码。

    相反,如果您将变量放在while 中,因为变量的本质是它们可以变化(更改),编译器的静态分析不会识别无法访问的代码。 (即使在许多情况下,您或我可以看到它并说“代码永远不会运行”;编译器的分析相当肤浅,这不是它的主要工作。您可以使用更强大的分析和代码覆盖工具使用。)

    关于if (false),这是JLS has to say about it:

    例如,以下语句会导致编译时错误:

    while (false) { x=3; }

    因为声明x=3;无法到达;但表面上类似的情况:

    if (false) { x=3; }

    不会导致编译时错误。优化编译器可能会意识到语句x=3; 将永远不会被执行,并且可能会选择从生成的类文件中省略该语句的代码,但语句x=3; 在此处指定的技术意义上不被视为“不可访问” .

    这种不同处理的基本原理是允许程序员定义“标志变量”,例如:

    static final boolean DEBUG = false;

    然后写代码如:

    if (DEBUG) { x=3; }

    这个想法是应该可以将DEBUG 的值从 false 更改为 true 或从 true 更改为 false,然后正确编译代码,而无需对程序文本进行其他更改。

    【讨论】:

    • 那么第二种情况呢?以及为什么if(false){ } 执行时没有错误。
    • @coders:添加了关于if (false)的进一步说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    相关资源
    最近更新 更多