Till now I manage to find all answers I need but this one confusing me. Let\'s say we have example code:
public class Animal {
private String species;
priv
Yes, when specifying only a single statement, its value is automatically returned from the lambda.
Then, since Runnable is a Functional Interface, it can be defined as a lambda. The return type is void
, so any return value inside the lambda will be ignored.
Does this mean that, behind the scenes, Java adds keyword return to code in the first case?
No, The compiler generates byte code, and it might generate the same byte code but it doesn't change the syntax and then compile it again.
we wanted to ignore boolean return type of method.
It has the option of ignoring a value based on what functional interfaces it is considering.
a -> a.canHop()
could be
(Animal a) -> { return a.canHop(); }
or
(Animal a) -> { a.canHop(); }
based on context, however it favours the first if possible.
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?
Saving the return type you can see it's a Callable<Integer>
final Future<Integer> submit = es.submit(() -> counter++);
To try yourself, here is a longer 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's 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
take a Runnable
so Future.get()
returns null
The second submit
defaults to being a Callable
so Future.get()
returns 2
The third submit
can only be a void
return value so it must be a Runnable
so Future.get()
returns null
You are confused about the scope of the return
statement. The return
statement (whether inserted as bytecode by the compiler or as source code by the programmer) returns from the lambda, and not from the method that calls the lambda.
void foo() {
Supplier<String> s = () -> { return "bar" };
String s = s.get(); // s is assigned to "bar"
// Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method
System.out.println("This will print");
}