【问题标题】:While(false) causes unreachable statement compilation errorWhile(false) 导致无法访问的语句编译错误
【发布时间】:2013-05-02 19:45:02
【问题描述】:

我最近在发布之前从我们的代码库中删除了一段代码,并使用了 if(false) 语句来阻止执行:

if (false) {
    ArrayList<String> list = new ArrayList<String>();
    ...
}

这编译得很好,并且会阻止执行有问题的代码块(对或错,这不是当前的论点)。

但是,有点意外,我将上面的块更改为:

while (false) {
    ArrayList<String> list = new ArrayList<String>();
    ...
}

并收到无法访问的语句编译错误。

我很欣赏编译错误并理解其中的原因,但是,我很难理解这两个块之间的区别,以及为什么前者编译得很好,而后者在它们都有无法访问的语句时却不能。

【问题讨论】:

  • 我猜do-whileif 更容易出错。这应该是后一种情况导致错误的原因。
  • 我的猜测是编译器作者的初衷是让两者都导致无法访问的错误。但是,由于编程实践中人们通常使用 if(false) 禁用代码,因此允许它作为一种特殊情况。

标签: java while-loop


【解决方案1】:

在这两种情况下,编译器都会报错,因为大括号之间的代码本质上是没有意义的,但是 if (false) 被保留在 Java 中以模拟 C/C++ 预处理器 #if 0,这很常见禁用部分代码进行测试或调试的方法。

编辑:作为参考,“条件编译”在 Java 语言规范的 chapter 14.21 末尾有详细说明。

【讨论】:

  • 实际上使用 if(false) 禁用代码的编程实践早于 C/C++ 的出现。
  • 公平。但不是unreachable statement error 部分。 Java 架构师应该做出决定:要么在编译时将两者都报告为死代码,要么不报告。至少,他们应该使用不同的、直接的语法来模拟#if 0。例如,disabled {} 或类似的东西。
  • 是的,我同意。正如我在上面评论的那样,我打赌最初两者确实导致了错误,然后他们为 if(false) 取消了它,因为程序员讨厌它。这将是一个很好的候选问题,可以发送给 James Gosling。
  • @Stefano 的行为有什么问题?它在不常见的情况下标记可能的程序员错误,同时允许常见的技巧。
  • 它不只是标记(这可能没问题),它会引发编译错误。我反对这个规则的例外,主要有两个原因。首先,最小惊讶原则:如果编译器说它将捕获并报告无法访问的语句,我希望javac 实际捕获并报告所有 无法访问的语句,没有例外。其次,if (false) {} 里面的块仍然被编译器解析,所以里面的任何语法错误/不完整的存根都会被报告;在 C++ 中,编译器永远不会看到由 #if 0 包裹的块。
【解决方案2】:

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

但是,Java 对“if (false) { ... }”做了一个特殊的例外,因为程序员在开发过程中经常使用这个结构来临时禁用部分程序。这就是编译器接受此语句的原因。

如果您对细节感兴趣,请参阅 Java 语言规范对无法访问语句的描述 @http://docs.oracle.com/javase/specs/#14.21。"

引用自http://www.coderanch.com/t/266678/java-programmer-SCJP/certification/false-false

【讨论】:

    猜你喜欢
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    相关资源
    最近更新 更多