编译器如何知道在 ExecutorService 中提交(Callable<T> 任务)或提交(Runnable 任务)时使用哪个 lambda?
How compiler knows which lambda to use in submit(Callable<T> task) or submit(Runnable task) in ExecutorService?
submit() method accepts both Runnable and callable as parameters. but
it returns Future when we send callable interface as a parameter.
所以当 lambda 发布时
() -> {}
编译器如何知道要使用哪个功能接口?可调用还是可运行? AFAIK 编译器不够聪明,无法分析表达式 return 是否存在,或者我错了吗?
对于任何 T
,lambda 表达式 () -> {}
与 Callable<T>
不兼容,而它 与 Runnable
兼容.因此选择 Runnable
重载。
JLS 的 15.27.3 and 15.27.2 部分解释了为什么会这样。
A lambda expression is compatible in an [...] invocation context [...] with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of the ground target type derived from T.
这里Callable<T>
的地面目标类型还是Callable<T>
。让我们看看“一致”是什么意思:
A lambda expression is congruent with a function type if all of the following are true:
[...]
- If the function type's result is a (non-void) type
R
, then either i) the lambda body is an expression that is compatible with R
in an assignment context, or ii) the lambda body is a value-compatible block, and each result expression (§15.27.2) is compatible with R
in an assignment context.
“值兼容块”定义为:
A block lambda body is value-compatible if it cannot complete normally (§14.21) and every return statement in the block has the form return Expression;
.
还有:
In a value-compatible block lambda body, the result expressions are any expressions that may produce an invocation's value. Specifically, for each statement of the form return Expression ;
contained by the body, the Expression
is a result expression.
因此,“编译器不够智能,无法分析表达式 return 是否存在”的说法是错误的。任何 Java 编译器都需要遵循规范所说的内容,并分析块是否正常完成(大致意味着完成 运行 而没有到达 return
或 throw
语句)。
在() -> {}
的情况下。没有 return 语句,因此块总是正常完成。
submit() method accepts both Runnable and callable as parameters. but it returns Future when we send callable interface as a parameter.
所以当 lambda 发布时
() -> {}
编译器如何知道要使用哪个功能接口?可调用还是可运行? AFAIK 编译器不够聪明,无法分析表达式 return 是否存在,或者我错了吗?
对于任何 T
,lambda 表达式 () -> {}
与 Callable<T>
不兼容,而它 与 Runnable
兼容.因此选择 Runnable
重载。
JLS 的 15.27.3 and 15.27.2 部分解释了为什么会这样。
A lambda expression is compatible in an [...] invocation context [...] with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of the ground target type derived from T.
这里Callable<T>
的地面目标类型还是Callable<T>
。让我们看看“一致”是什么意思:
A lambda expression is congruent with a function type if all of the following are true:
[...]
- If the function type's result is a (non-void) type
R
, then either i) the lambda body is an expression that is compatible withR
in an assignment context, or ii) the lambda body is a value-compatible block, and each result expression (§15.27.2) is compatible withR
in an assignment context.
“值兼容块”定义为:
A block lambda body is value-compatible if it cannot complete normally (§14.21) and every return statement in the block has the form
return Expression;
.
还有:
In a value-compatible block lambda body, the result expressions are any expressions that may produce an invocation's value. Specifically, for each statement of the form
return Expression ;
contained by the body, theExpression
is a result expression.
因此,“编译器不够智能,无法分析表达式 return 是否存在”的说法是错误的。任何 Java 编译器都需要遵循规范所说的内容,并分析块是否正常完成(大致意味着完成 运行 而没有到达 return
或 throw
语句)。
在() -> {}
的情况下。没有 return 语句,因此块总是正常完成。