【问题标题】:Unreachable code while loop循环中无法访问的代码
【发布时间】:2014-01-22 05:28:20
【问题描述】:

当我编译这段代码时

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;
        }
    }

一切正常。

谁能告诉我这种行为背后的原因。

【问题讨论】:

标签: java while-loop


【解决方案1】:

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

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

但是这会编译,因为 result 不再是一个常量变量:

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

有关类似讨论,另请参阅:Why does the Java compiler not understand this variable is always initialized?

【讨论】:

    【解决方案2】:

    以下语句中常量false的使用

      while(false)
    

    在编译时被解析为 false,因此编译器会抱怨无法访问的代码。

    但是当你改用变量时:

        boolean result = false;
        while(result)
    

    编译器在编译时不确定它的值,因此不会抱怨。

    【讨论】:

    • 对于提问者来说可能太高级了,但可以在调用 while(result) 之前将 result 的值修改为 true,从而产生 hacked 执行到 while 循环内的代码。这在while(false) 中不会发生,因此代码确实无法访问(编译器会忽略它,甚至不会将其转换为字节码)。
    【解决方案3】:

    编译器的行为在 Java 语言规范的 14.21. Unreachable Statements 部分中精确指定。

    这是一个关键的引用,它直接解决了您的问题:

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

    【讨论】:

      【解决方案4】:

      Java 使用简单的流分析算法来查找最常见的无法访问代码的情况,并且所有此类无法访问的代码块都将被标记为编译时错误。这就是为什么您的“while (false) { ... }”语句会产生错误的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-06
        • 2018-02-23
        • 1970-01-01
        • 2019-11-30
        • 1970-01-01
        • 2014-07-30
        相关资源
        最近更新 更多