Why compiler gives me "return statement missing" erorr?
All possible conditional branches (if-else) contain a return statement.
But if I have the same if-else-if-else construct alone (not inside for() loop) - it compiles fine, without producing this "return statement missing" erorr?
public Resume get(String uuid) {
// compiler shall know that array is not empty!
final Resume[] storage = new Resume[100]; // same for static final
// is executed at least once - see above!
for(Resume resume : storage) {
if (resume == null) {
return null;
} else if (resume.uuid.equals(uuid)){
return resume;
} else {
return null;
}
}
// return statement is missing !!!
}
I could understand the compiler - it is afraid that the loop would never execute if the array named storage is empty. Why compiler ignores the size of the array? But it is just a half of problem with advanced for loop.
Let's take a regular for loop, totally independant of storage array size.
public Resume get(String uuid) {
Resume resume = new Resume();
// being a static final field produces same compile error...
final int LIMIT = 100;
// LIMIT is known to compiler, since it is final primitive.
// for loop execution not dependent on storage array being empty
for (int i = 0; i < LIMIT; i++) {
if (resume == null) {
return null;
} else if (resume.uuid.equals(uuid)){
return resume;
} else {
return null;
}
}
// return null; //statement is missing !!!; //
}
What explains this second for loop problem?
P.S. I think it is because things like "i < LIMIT" (even LIMIT being final) do not evaluate to true during compilation, true appears only at runtime, so at compile-time compiler is afraid just-in-case ;)
storageis empty? Compiler doesn't assume its size, it takes into consideration scenario where loop may not iterate even once.getthat doesn't return anything: The path taken ifstorageis empty. You and I know that it isn't empty, but the compiler doesn't work down to that level of detail. Separately, it doesn't make any sense to use a loop if you're only ever going to have a single iteration (because you're returning immediately).storageis not empty, as tthe method will return during the first iteration. Remove the lastelseblock to go through the listLIMITis final so compiler can assume its value,iis not so compiler will not assume its value (even if we know that it will be0at start) probably because that value will be set at runtime (compiler is not that smart yet, although it would be nice if it was). So at compilation-timei < LIMITis similar to? < LIMITso compiler can't evaluate that expression to betruewhich would guarantee that loop would iterate at least once. Problem disappears when instead ofi < LIMITyou will compare two compilation-time constants or usetrueinstead of condition.