Lambda Expressions in Java8
A lambda expression supplies an implementation for a functional interface. This is what your code snippet does.
Your call to invoke
passes a lambda expression with no arguments that returns a value (a boolean
in your case). Therefore it matches Object invoke(Callable c)
, and not void invoke(Runnable r)
(since a Callable
's call
method has a return value while a Runnable
's run
method doesn't return anything).
invoke(() -> {System.out.println("something");});
will call void invoke(Runnable r)
, since in this case the lambda expression has no return type.
only when we Implement a interface and override its methods
That's, more or less, what you do here. Not methods, but just one method: call()
. This () -> true
part is your implementation of Callable#call()
.
In other words, this line:
String s = (String) invoke(() -> true);
would be totally equivalent with this one:
String s = (String) invoke(new Callable() {
@Override
public Object call() throws Exception {
return true;
}
});
In the following line
String s = (String) invoke(() -> true);
It is actually invoke(Callable)
that is getting called. The reason is:
() -> true
is a lambda expression that has zero formal parameter and return a result.- Such a signature (zero parameter, single result) is compatible with the functional method
call()
of theCallable
interface. Note that the interface does not need to have the@FunctionalInterface
annotation, it just needs to have a single abstract method.
If you want to invoke invoke(Runnable)
instead, you will need to create a lambda that is compatible with a functional method that takes zero parameter and returns no result (i.e. conforms with the signature of run()
). Something like this:
invoke(() -> System.out.println("foo"));
Which just prints foo
when ran.