Bear with me, the introduction is a bit long-winded but this is an interesting puzzle.
I have this code:
public class Testcase {
public static void m
I wrongly considered this a bug, but it appears to be correct according to §15.27.2. Consider:
import java.util.function.Supplier;
public class Bug {
public static void method(Runnable runnable) { }
public static void method(Supplier supplier) { }
public static void main(String[] args) {
method(() -> System.out.println());
method(() -> { throw new RuntimeException(); });
}
}
javac Bug.java javap -c Bug
public static void main(java.lang.String[]);
Code:
0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable;
5: invokestatic #3 // Method add:(Ljava/lang/Runnable;)V
8: invokedynamic #4, 0 // InvokeDynamic #1:get:()Ljava/util/function/Supplier;
13: invokestatic #5 // Method add:(Ljava/util/function/Supplier;)V
16: return
This happens with jdk-11-ea+24, jdk-10.0.1, and jdk1.8u181.
zhh's answer led me to find this even simpler test case:
import java.util.function.Supplier;
public class Simpler {
public static void main(String[] args) {
Supplier s = () -> { throw new RuntimeException(); };
}
}
However, duvduv pointed out §15.27.2, in particular, this rule:
A block lambda body is value-compatible if it cannot complete normally (§14.21) and every return statement in the block has the form return Expression;.
Thus, a block lambda is trivially value-compatible even if it contains no return statement at all. I would have thought, because the compiler needs to infer its type, that it would require at least one return Expression;. Holgar and others have pointed out that this is not necessary with ordinary methods such as:
int foo() { for(;;); }
But in that case the compiler only needs to ensure there is no return that contradicts the explicit return type; it doesn't need to infer a type. However, the rule in the JLS is written to allow the same freedom with block lambdas as with ordinary methods. Perhaps I should have seen that sooner, but I did not.
I filed a bug with Oracle but have since sent an update to it referencing §15.27.2 and stating that I believe my original report to be in error.