方法参数的目标类型转换,Lambda

Target type casting for method arguments , Lambda

考虑以下两个功能接口(java.lang.Runnable and java.util.concurrent.Callable<V>):

public interface Runnable {
    void run();
}

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

假设您overloaded方法调用如下:

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

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

考虑下面的方法调用

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

这将调用 invoke(Callable) 。但是怎么样?编译器如何确定类型为可调用?我不明白我读过的 Oracle 文档。

您的 () -> "done" 是一个 returns 值的 lambda,没有输入参数。由于 Runnable 既没有 returns 值也没有输入参数,因此 () -> "done" 无法匹配重载的签名 invoke(Runnable).

如果您要添加带有 Supplier 的签名(或任何其他不带参数但 returns 值的功能接口),它将无法确定您是否要调用 CallableSupplier 版本。

因为 () -> "done" returns 一个字符串值 "done" 这就是 [=14= 的 call 方法]负责在:

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

另一方面 run 是一个 void 方法,匹配类型 Runnable 的可能是一个无效调用,例如:

invoke(() -> System.out.println("done"))