问题 1:
为什么下面的代码编译时没有返回语句?
public int a() {
while(true);
}
注意:如果我在一段时间后添加 return,则会收到 Unreachable Code Error
。
问题 2:
另一方面,为什么下面的代码会编译,
public int a() {
while(0 == 0);
}
即使以下没有。
public int a(int b) {
while(b == b);
}
最佳答案
Question 1:
Why does the following code compile without having a return statement?
public int a() { while(true); }
这被 JLS§8.4.7 覆盖:
If a method is declared to have a return type (§8.4.5), then a compile-time error occurs if the body of the method can complete normally (§14.1).
In other words, a method with a return type must return only by using a return statement that provides a value return; the method is not allowed to "drop off the end of its body". See §14.17 for the precise rules about return statements in a method body.
It is possible for a method to have a return type and yet contain no return statements. Here is one example:
class DizzyDean { int pitch() { throw new RuntimeException("90 mph?!"); } }
由于编译器知道循环永远不会终止(当然,true
总是正确的),它知道函数不能“正常返回”(丢弃其主体的末尾),并且因此没有return
也没关系。
Question 2:
On the other hand, why does the following code compile,
public int a() { while(0 == 0); }
even though the following does not.
public int a(int b) { while(b == b); }
在 0 == 0
的情况下,编译器知道循环永远不会终止(即 0 == 0
将始终为真)。但它不知道对于 b == b
。
为什么不呢?
编译器理解 constant expressions (§15.28) .报价 §15.2 - Forms of Expressions (因为奇怪的是这句话不在 §15.28 中):
Some expressions have a value that can be determined at compile time. These are constant expressions (§15.28).
在您的 b == b
示例中,因为涉及到一个变量,所以它不是一个常量表达式,也没有指定在编译时确定。 我们可以看到在这种情况下它总是正确的(尽管如果 b
是一个 double
,作为 QBrute pointed out,我们可以很容易被 Double.NaN
愚弄,即 not ==
itself ),但 JLS 仅指定常量表达式在编译时确定,它不允许编译器尝试计算非常量表达式。河口网raised a good point为什么不这样做:如果你开始尝试在编译时确定涉及变量的表达式,你会在哪里停下来? b == b
是显而易见的(呃,对于非 NaN
值),但是 a + b == b + a
呢?还是 (a + b) * 2 == a * 2 + b * 2
?在常数处画线是有意义的。
因此,由于它没有“确定”表达式,编译器不知道循环永远不会终止,因此它认为该方法可以正常返回——这是不允许的,因为它需要使用 返回
。所以它提示缺少 return
。
关于具有返回类型的 Java 方法在没有返回语句的情况下编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31050114/