无法到达的代码——while循环

3

当我编译这段代码时

public static void main(String [] args) {

        int x = 0;        

        while(false)
        {                        
            System.out.println(hello);
        }
    }

这段代码出现了编译时错误,提示代码无法到达。

但是当我修改了这段代码:

public static void main(String [] args) {

        int x = 0;        
        boolean result = false;
        while(result)
        {                        
            x=4;
        }
    }

它正常工作。

有人能告诉我这种行为背后的原因吗?


@assylias 好的,撤回了关闭投票。 - Adam Siemion
虽然这是Java,但请参见:https://communities.coverity.com/blogs/development-testing-blog/2013/11/06/c-reachability - 我认为推理是类似的。 - Rowland Shaw
4个回答

9

这是因为boolean result = false不是常量表达式,而false则是。如果你尝试以下代码,它也不会编译,因为result现在是一个常量:

final boolean result = false;
while(result) { x=4; }

然而,这样编译是可以的,因为`result`不再是一个常量变量:
final boolean result;
result = false;
while(result) { x=4; }

请参阅:为什么Java编译器无法理解这个变量始终已初始化?进行类似的讨论。

6

以下语句中使用了常量false

  while(false)

在编译时,is resolved为false,因此编译器会报告无法访问的代码错误。

但是,当您使用变量时:

    boolean result = false;
    while(result)

编译器在编译时无法确定 "it" 的值,因此不会报错。

也许对提问者来说有些高级,但是在调用while(result)之前,将result的值修改为_true_是可能的,从而导致执行被_hacked_,并且可以进入while循环内部的代码。这在while(false)中不可能发生,因此该代码确实是无法到达的(编译器会忽略它,甚至不会将其转换为字节码)。 - ADTC

4
编译器的行为在Java语言规范的第14.21节“不可达语句”中有明确的说明。
以下是关键引用,直接回答了您的问题:
这一节详细解释了“可达”这个词。其思想是必须从包含该语句的构造函数、方法、实例初始化程序或静态初始化程序的开头到该语句本身存在一些可能的执行路径。该分析考虑了语句的结构。除了while、do和for语句的条件表达式具有常量值true的特殊处理外,表达式的值在流程分析中不被考虑。

1
Java使用简单的流分析算法来查找大多数不可达代码情况,所有这些不可达代码块都将被标记为编译时错误。这就是为什么你的“while (false) { ... }”语句会产生错误的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接