I have the following piece of code which obviously can not be compiled:
jshell> static int counter = 0;
counter ==> 0
jshell> Runnable r = () -> counter;
| Error:
| incompatible types: lambda body is not compatible with a void functional interface
| (consider using a block lambda body, or use a statement expression instead)
| Runnable r = () -> counter;
|
This is understandable, since the signature for the Runnable
's run
is void run()
. Now, if I have the following lambda, this will compile just fine:
jshell> static int counter = 0;
counter ==> 0
jshell> Runnable r = () -> counter++;
r ==> $Lambda$23/0x0000000800c0b260@3941a79c
Why does this piece of code compile, knowing that counter++
will still return an integer?
Also, what makes it more confusing is that this code can also be compiled:
jshell> Supplier<Integer> f = () -> counter++;
f ==> $Lambda$22/0x0000000800c0a410@12edcd21
I tried compiling the code above using Java 17's jshell.
In the Runnable
, the returned value is ignored; the main part (why it compiles) is that there is a statement in it.
It does return a value, so it's also a Supplier
. It also manipulates counter
(as a side effect), but that doesn't matter for fulfilling the functional interface. .