简体   繁体   中英

What's wrong with my return statement?

Why this code is wrong ? When I change "else if(this.power >= p)" into only "else" , it's right. Can anybody give me a hint?

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;
    }
}

To a human reader looking at the code it seems that either the first return will be hit, or the second, but the compiler can't be sure. To the compiler it looks like:

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

and it needs to know, what will the method return if neither condition1 nor condition2 is true?

Whereas if you change it to a straight else ,

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

then it is certain that one of the two return statements must be hit.

In fact in your method there is a chance that neither condition will be met: if one of the numbers you are comparing is NaN (the special floating point value representing "not a number"), then both of your if conditions will be false, and the method would have no return value.

There is also theoretically a possibility that some code running in another thread might alter the value of this.power between the first if check and the second, which could lead to both conditions evaluating to false. So it is not possible for the compiler to know for certain that one of the conditions will be met, even if they were logically complementary.

What happens if we don't enter any of your conditional branches? Java can't determine that you'll be able to because else if implies that there may not be another conditional branch to check.

Phrased another way, there's an implicit else block that does nothing. Since you declare a return type, having this implicit else block do nothing is an error.

An else block is always guaranteed to execute, so you will not run into the same situation with else , which is probably what you intended to use in the first place.

Think in the case of a flowchart.

  • If ( this.power < p ), then
    • Set power to 0
    • Return false
  • Else if ( this.power >= p ), then
    • Subtract p from power
    • Return true
  • Else (implied)
    • Do nothing <- this is the error

Because if you add if into the second else there might be a condition where neither of the condition will be satisfied and method will match to no return statement.

Consider this simple example:

Consider x=5; below code will match no return statement because it doesn't satisfies any condition.

if(x>5){
 return true;
}
else if(x < 5){
 return false;
}

You can reproduce this error with even shorter code:

 public int doSomething() {
    if(true) {
        return 0;
    }
 }

This method generates compiler error missing return statement

Compiler doesn't perform intelligent static analysis of your code. It just checks statements according to specification.

Java Language Specification 8.4.7 "Method body" states that:

If a method is declared to have a return type, then a compile-time error occurs if the body of the method can complete normally.

So, compiler just checks if these statements can complete normally.

JLS 14.9.1 "The if-then Statement" :

If the value is true, then the contained Statement is executed; the if-then statement completes normally if and only if execution of the Statement completes normally.

If the value is false, no further action is taken and the if-then statement completes normally.

As you can see by specification if statement can complete normally. That's why a compile-time error occurs.

On the other hand, by JLS 14.9.2 "The if-then-else Statement" :

If the value is true, then the first contained Statement (the one before the else keyword) is executed; the if-then-else statement completes normally if and only if execution of that statement completes normally.

If the value is false, then the second contained Statement (the one after the else keyword) is executed; the if-then-else statement completes normally if and only if execution of that statement completes normally.

As you can see if-then-else completes if and only if one of its blocks completes normally. In your example both of them contain return statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM