我的退货声明有什么问题?

时间:2014-12-22 23:31:15

标签: java if-statement

为什么这段代码错了?当我将"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;
    }
}

4 个答案:

答案 0 :(得分:6)

对于查看代码的人类读者来说,似乎第一个return将被命中,或者第二个,但编译器无法确定。对于编译器,它看起来像:

 if (condition1) {
     ...
     return false;
 } else if (condition2) {
     ...
     return true;
 }

并且需要知道,如果condition1condition2都不为真,该方法会返回什么?

而如果您将其更改为直线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
    • 返回false
  • 如果(this.power >= p),那么
    • p
    • 中减去power
    • 返回true
  • 其他(暗示)
    • 什么都不做&lt; - 这是错误

答案 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语句。