0

以下代码块给了我一个编译时错误。

        while(false)
        {
          System.out.println("HI");
        }

该错误表示存在无法访问的语句。但是下面的代码编译

   boolean b=false;
   while(b)
   {
        System.out.println("Hi");
    }

我能想到的就是这个-> In case-1 as false 是一个文字,所以编译器发现它无法访问,如果在运行时检查 while 条件块中的 case 2 变量 b,所以没有编译错误?

4

5 回答 5

3

编译器编写者无法决定将哪些条件标记为错误 - 规则在 Java 语言规范中,对于14.21 Unreachable Statements中的这个问题。

相关句子是:“如果while语句可达且条件表达式不是值为假的常量表达式,则包含的语句是可达的。”

在每种情况下,您都有一个可访问的 while 语句。在第一个版本中,false是一个值为 false 的常量表达式,因此包含的语句不被认为是可达的。在第二个版本中,bis 根本不是一个常量表达式,因此包含的语句被视为可访问的。

添加final到声明中b会将 while 条件更改为值为 false 的常量表达式,从而使包含的语句再次无法访问。

为 JLS 中的编译时错误指定规则的好处是,所有 Java 编译器都应该接受相同的程序集。规则一般不要求编译器做数据流分析,大概是为了限制编写编译器的成本和难度。

于 2013-09-11T23:56:29.477 回答
2

编译器看到while(false),这永远不会是真的,所以你无法到达println. 这会引发错误。

同时,虽然while(b)也永远不会为真,但编译器不会自动知道这一点,因为b它不会自动为假,它是一个boolean碰巧有值的false,它可能会在某个时候改变。(它不在这里,但它可能有)。

为了使这一点更笼统,编译器将查看变量的类型,而不是变量实际上是什么。许多初级编程课程都有部分处理多态性和类型转换在某些情况下如何导致运行时错误,以及在其他情况下如何导致编译器错误。如果你碰巧上过这样的课程,你可以认为你的问题在这里有类似的解释。

于 2013-09-11T23:34:20.720 回答
2

这对我来说很有意义。While (false) 永远不会成功评估,而在 while(b) 的情况下 - b 的值可以在程序生命周期的某个时刻更新为 true。

于 2013-09-11T23:35:35.250 回答
1

编译器不是很聪明。它会找到一个可以证明是错误条件的块,然后它会哭。给它这样的东西,它javac甚至不会看起来那么远。对人类来说显而易见的东西对计算机来说不一定是显而易见的,反之亦然。

于 2013-09-11T23:32:28.300 回答
1

编译器看到while(false)并可以确定内部的块,而永远不会执行。

而在布尔值的情况下,b在运行时评估的值,所以它不会阻止你

于 2013-09-24T08:50:04.930 回答