3

Consider the following two functional interfaces ( java.lang.Runnable and java.util.concurrent.Callable<V>):

public interface Runnable {
    void run();
}

public interface Callable<V> {
    V call();
}

Suppose that you have overloaded the method invoke as follows:

void invoke(Runnable r) {
    r.run();
}

<T> T invoke(Callable<T> c) {
    return c.call();
}

Consider below method invokation

String s = invoke(() -> "done");

This will call invoke(Callable) . but How? How compliler is able to determine the Type as callable? I didn't understand from Oracle doc i have read.

Naman
  • 27,789
  • 26
  • 218
  • 353
Vipin CP
  • 3,642
  • 3
  • 33
  • 55

2 Answers2

6

Your () -> "done" is a lambda that returns a value and has no input parameters. Since Runnable neither returns a value nor has input parameters, () -> "done" can't match the signature of your overload invoke(Runnable).

If you were to add a signature with Supplier (or any other functional interface that takes no parameters but returns a value), it wouldn't be able to determine whether you want to call the Callable or the Supplier version.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
6

Since () -> "done" returns a string value "done" which is what the call method of a Callable is responsible for in:

String s = invoke(() -> "done"); 
// from impl. of 'invoke', the variable 's' is assigned value "done"

On the other hand run is a void method, what matches the type Runnable there could be a void call such as:

invoke(() -> System.out.println("done"))
Naman
  • 27,789
  • 26
  • 218
  • 353