Bas*_*ass 12 java lambda functional-programming java-8
在Java 1.8中,以下lambda表达式符合两个Runnable和Callable功能接口:
() -> {
throw new RuntimeException("FIXME");
}
Run Code Online (Sandbox Code Playgroud)
尽管如此,如果我将它提交给ExecutorService使用单参数方法,并忽略返回值(即没有可用的类型推断信息),ExecutorService#submit(Callable)则在编译时选择,除非我明确地将我的lambda转换为Runnable.
在上述情况下,编译器如何在重载方法之间进行选择,前提是Runnable并且Callable不共享任何公共层次结构,并且大多数特定类型规则不适用于此处?
我相信这是因为Callable声明了一个返回类型,而Runnable不是.
从JLS部分15.12.2.5开始,如果有一个明确最具体的类型,则选择具有最特定类型的重载.这就是它对大多数特定功能接口类型的说法:
如果T不是S的子类型且下列之一为真,则功能接口类型S比表达式e的功能接口类型T更具体(其中U1 ... Uk和R1是参数类型和返回类型捕获S的函数类型,V1 ... Vk和R2是T)函数类型的参数类型和返回类型:
如果e是显式类型的lambda表达式(第15.27.1节),则以下之一为真:
- R2无效......
Tis Runnable,Sis Callable,Callable更具体,因为它的返回类型不是void,因此Callable被选中
方法重载分辨率非常复杂,所以可能有一点我错过了,但我认为这就是它选择的原因 Callable