Search code examples
javalambda

Why does the following lambda compile when assigning it to Runnable?


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.


Solution

  • 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. .