Does this mean that behind the scenes Java adds a keyword to the code in the first case?
Not. The compiler generates bytecode and can generate the same bytecode, but it does not change the syntax and then compiles it again.
we wanted to ignore the boolean type of the return method.
It has the ability to ignore a value based on which functional interfaces it considers.
a -> a.canHop()
may be
(Animal a) -> { return a.canHop(); }
or
(Animal a) -> { a.canHop(); }
depending on the context, however, if possible, he endorses the former.
Consider ExecutorService.submit(Callable<T>) and ExecutorService.submit(Runnable)
ExecutorService es = Executors.newSingleThreadExecutor(); es.execute(() -> counter++); // has to be Runnable es.submit(() -> counter++); // Callable<Integer> or Runnable?
Keeping the return type, you can see its Callable<Integer>
final Future<Integer> submit = es.submit(() -> counter++);
To try yourself, here is a long example.
static int counter = 0; public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService es = Executors.newSingleThreadExecutor(); // execute only takes Runnable es.execute(() -> counter++); // force the lambda to be Runnable final Future<?> submit = es.submit((Runnable) () -> counter++); System.out.println(submit.get()); // returns a value so it a Callable<Integer> final Future<Integer> submit2 = es.submit(() -> counter++); System.out.println(submit2.get()); // returns nothing so it must be Runnable final Future<?> submit3 = es.submit(() -> System.out.println("counter: " + counter)); System.out.println(submit3.get()); es.shutdown(); }
prints
null 2 counter: 3 null
The first submit accepts a Runnable , so Future.get() returns null
The second submit defaults to Callable , so Future.get() returns 2
The third submit can only be the void return value, so it must be Runnable , so Future.get() returns null