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;
private boolean canHop;
private boolean canSwim;
public Animal(String speciesName, boolean hopper, boolean swimmer) {
species = speciesName;
canHop = hopper;
canSwim = swimmer;
}
public boolean canHop() { return canHop; }
public boolean canSwim() { return canSwim; }
public String toString() { return species; }
}
public interface CheckAnimal {
public boolean test(Animal a);
}
public class FindSameAnimals {
private static void print(Animal animal, CheckAnimal trait) {
if(trait.test(animal)){
System.out.println(animal);
}
public static void main(String[] args) {
print(new Animal("fish", false, true), a -> a.canHop());
}
}
OCA Study Guide (Exam 1Z0-808) book says that these two lines are equivalent:
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
Does this mean that, behind the scenes, Java adds keyword return to code in the first case?
If answer is YES then how next code compile (imagine everything else is in proper place):
static int counter = 0;
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> counter++));
if we know that signatures for execute and Runnable's run are:
void execute(Runnable command)
void run()
If answer is NO then how Java know when it need to return something and when not to? Maybe in
a -> a.canHop()
case we wanted to ignore boolean return type of method.
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.
It has the option of ignoring a value based on what functional interfaces it is considering.
could be
or
based on context, however it favours the first if possible.
Consider
ExecutorService.submit(Callable<T>)
andExecutorService.submit(Runnable)
Saving the return type you can see it's a
Callable<Integer>
To try yourself, here is a longer example.
prints
The first
submit
take aRunnable
soFuture.get()
returnsnull
The second
submit
defaults to being aCallable
soFuture.get()
returns2
The third
submit
can only be avoid
return value so it must be aRunnable
soFuture.get()
returnsnull
You are confused about the scope of the
return
statement. Thereturn
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.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 isvoid
, so any return value inside the lambda will be ignored.