问题1:

为什么下面的代码编译时没有 return 语句?

public int a() {
    while(true);
}

注意:如果我在一段时间后添加 return ,那么我会得到一个 Unreachable Code Error

问题2:

另一方面,为什么下面的代码会编译,
public int a() {
    while(0 == 0);
}

即使下面没有。
public int a(int b) {
    while(b == b);
}

最佳答案



这被 JLS§8.4.7 覆盖:



由于编译器知道循环永远不会终止(当然 true 始终为真),它知道该函数不能“正常返回”(从其主体的末尾处退出),因此没有 return 是可以的。



0 == 0 的情况下,编译器知道循环永远不会终止(0 == 0 将始终为真)。但它 不知道 b == b

为什么不?

编译器理解 constant expressions (§15.28) 。引用 §15.2 - Forms of Expressions(因为奇怪的是这句话不在 §15.28 中):



在您的 b == b 示例中,由于涉及变量,因此它不是常量表达式,并且未指定在编译时确定。 我们可以看到,它总是要在这种情况下,真正的(尽管如果b是一个double,作为QBrute pointed out,我们可以很容易地通过Double.NaN,这是not == itself上当),但JLS唯一指定该常量表达式确定在编译时,它不允许编译器尝试评估非常量表达式。 bayou.io raised a good point 为什么不:如果你开始尝试在编译时确定涉及变量的表达式,你会在哪里停下来? b == b 很明显(呃,对于非 NaN 值),但是 a + b == b + a 呢?还是 (a + b) * 2 == a * 2 + b * 2 ?在常量处画线是有道理的。

因此,由于它不“确定”表达式,编译器不知道循环永远不会终止,因此它认为该方法可以正常返回 - 这是不允许的,因为它需要使用 return 。所以它提示缺少 return

关于具有返回类型的 Java 方法在没有返回语句的情况下编译,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31050114/

10-14 09:39
查看更多