Reputation: 310
I have this code:
public class Sample {
public static void useCallable(Callable<Integer> expression){}
public static void main(String[] args){
useCallable(()->{throw new IOException();});
}
}
which compiles and runs fine.
However, shouldn't Callable<Integer>
take nothing as input and return an Integer?
()->{throw new IOException();}
doesn't return anything, so why is it a valid Callable<Integer>
expression?
Upvotes: 1
Views: 93
Reputation: 50716
For the same reason this method compiles:
Integer foo() throws Exception {
throw new IOException();
}
Which compiles for the same reason as this method:
Integer foo() throws Exception {
if (hasFoo()) {
return getFoo();
} else {
throw new IOException();
}
}
To quote the JLS,
If a method is declared to have a return type (§8.4.5), then a compile-time error occurs if the body of the method can complete normally (§14.1).
What does "complete normally" mean? According to the JLS (emphasis mine),
If all the steps are carried out as described, with no indication of abrupt completion, the statement is said to complete normally. However, certain events may prevent a statement from completing normally:
The
break
(§14.15),continue
(§14.16), andreturn
(§14.17) statements cause a transfer of control that may prevent normal completion of statements that contain them.Evaluation of certain expressions may throw exceptions from the Java Virtual Machine (§15.6). An explicit
throw
(§14.18) statement also results in an exception. An exception causes a transfer of control that may prevent normal completion of statements.
In other words, a method with a return type must either return or throw. Yours does the latter, so it's valid.
Upvotes: 4