为什么这段代码错了?当我将"else if(this.power >= p)"
更改为仅"else"
时,它是正确的。任何人都可以给我一个暗示吗?
public boolean useBattery(double p) {
if(this.power < p) {
this.power = 0.0;
return false;
} else if(this.power >= p) {
this.power = this.power - p;
return true;
}
}
答案 0 :(得分:6)
对于查看代码的人类读者来说,似乎第一个return
将被命中,或者第二个,但编译器无法确定。对于编译器,它看起来像:
if (condition1) {
...
return false;
} else if (condition2) {
...
return true;
}
并且需要知道,如果condition1
和condition2
都不为真,该方法会返回什么?
而如果您将其更改为直线else
,
if (condition1) {
...
return false;
} else {
...
return true;
}
然后肯定必须命中两个return
语句中的一个。
实际上在你的方法中,有可能不会满足任何条件:如果你要比较的一个数字是NaN
(表示“不是数字”的特殊浮点值),那么您的if
条件将为false,并且该方法没有返回值。
this.power
检查和第二个检查之间改变if
的值,这可能导致两个条件评估为false。因此,编译器无法确定是否满足其中一个条件,即使它们 在逻辑上是互补的。
答案 1 :(得分:3)
如果我们不进入您的任何有条件分支,会发生什么? Java无法确定您是否能够执行,因为else if
意味着可能没有其他条件分支可供检查。
另一种说法是,隐含的else
块无效。由于您声明了一个返回类型,因此使用此隐式else
块不会产生任何错误。
始终保证else
块可以执行,因此您不会遇到与else
相同的情况,可能您打算在第一个使用的内容的地方。
考虑流程图。
this.power < p
),那么
power
设为0 this.power >= p
),那么
p
power
答案 2 :(得分:1)
因为如果你将if添加到第二个else中,那么可能存在一个条件,即条件都不会满足,并且方法将匹配no return语句。
考虑这个简单的例子:
考虑x = 5;下面的代码将匹配no return语句,因为它不满足任何条件。
if(x>5){
return true;
}
else if(x < 5){
return false;
}
答案 3 :(得分:1)
您可以使用更短的代码重现此错误:
public int doSomething() {
if(true) {
return 0;
}
}
此方法会生成编译器错误missing return statement
编译器不会对您的代码执行智能静态分析。它只是根据规范检查语句。
Java语言规范8.4.7 "Method body"声明:
如果声明某个方法具有返回类型,则如果该方法的主体可以正常完成,则会发生编译时错误。
因此,编译器只检查这些语句是否可以正常完成。
JLS 14.9.1 "The if-then Statement":
如果值为true,则执行包含的Statement;当且仅当Statement的执行正常完成时,if-then语句才正常完成。
如果值为false,则不执行进一步操作,if-then语句正常完成。
正如您可以通过规范看到if语句可以正常完成。这就是发生编译时错误的原因。
另一方面,JLS 14.9.2 "The if-then-else Statement":
如果值为true,则执行第一个包含的Statement(else关键字之前的那个);当且仅当该语句的执行正常完成时,if-then-else语句才能正常完成。
如果值为false,则执行第二个包含的Statement(else关键字后面的那个);当且仅当该语句的执行正常完成时,if-then-else语句才能正常完成。
正如你所看到的那样if-then-else当且仅当其中一个块正常完成时才完成。在您的示例中,它们都包含return语句。