Missing return statement in for loop

2020-04-15 05:15发布

问题:

I have a for loop that returns values from an array.

public static String getPieces(){
        for(int y=0; y<=7; y++)
            for(int x=0; x<=7; x++)
                return piece[x][y];
}

There is a return statement clearly in the method that will return every time it is called. Why does it say missing return statement?

回答1:

Besides the loop being completely pointless (because it will return piece[0][0]), adding an extra return line might help you:

public static String getPieces(){
        for(int y=0; y<=7; y++){
            for(int x=0; x<=7; x++){
                return piece[x][y];
            }
        }

}

Since you stated that you want to return 64 values, you'll have to return an array. 

public static ArrayList<String> getPieces(){
    ArrayList<String> strings = new ArrayList<String>();
    for(int y = 0; y <= 7; y++){
        for(int x = 0; x <= 7; x++){
            strings.add(piece[x][y]);
        }
    }
    return strings;
}


回答2:

JLS §8.4.7. Method Body says this:

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 (§14.1).

Where the definition of complete normally is not competing abruptly. A return statement is something that completes abruptly.

Next, assuming this syntax for a for statement:

for ( ForInit_opt ; Expression_opt ; ForUpdate_opt ) Statement

The JLS §14.14.1.2. Iteration of for Statement states this :

Next, a for iteration step is performed, as follows:

  • If the Expression is present, it is evaluated. If the result is of type Boolean, it is subject to unboxing conversion (§5.1.8).

    • If evaluation of the Expression or the subsequent unboxing conversion (if any) completes abruptly, the for statement completes abruptly for the same reason.

So, the fact that the Expression might complete abruptly means that the for loop will complete abruptly as well, for the same reason, which is of course not "returning". So, the return statement might be unreachable.

However, we both know that it will be always reached. But that is a shortcoming of the compiler intelligence. If you remove the Expressions (they are optional), or replace them with true, the compiler doesn't complain. Your code is basically this:

// This snippet won't work as method body
for (int i = 0; i < 10; ++i)
{
    return "Hello"; 
}

In comparison with this:

// This snippet compiles fine
for (int i = 0; true; ++i)
{
    return "Hello";
}

This means that there are two options:

  • i < 10 can complete abruptly
  • the compiler can't determine wether i <= 10 evaluates to true or not, even if you declared int i = 0.

I went searching through the JLS and didn't find anything about abrupt completion of a simple i < 10 statement. So, I guess that the reason why this happens is actually the second one: he can't be sure that i < 10 will evaluate to true for at least once.


So, in order to make the compiler shut up about the fact that he is not certain about the return statement actually being called, you can let the method complete abruptly by yourself:

for (int i = 0; i < 10; ++i)
{
    return "Hello"; 
}
throw new RuntimeException("Should never, ever, reach this point!");


回答3:

because return statement is under for block.

As you have mentioned return type is String and your method has to have return tye. But with your program compiler does not know in advance that flow does not go under for loop and no return is possible. So compiler is extra smart. Is n't it :)

Try

public static String getPieces(){
       String result = null;
        for(int y=0; y<=7; y++)
            for(int x=0; x<=7; x++)
                result= piece[x][y];

        return result;
}

it will work