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 the Callable 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.