Lambda 转换规则

Lambda casting rules

我很好奇为什么 return 类型的 lambda 不能转换为 Runnable 而非 void 方法引用可以。

Runnable r1 = () -> 1; // not allowed
// error: incompatible types: bad return type in lambda expression
// int cannot be converted to void

Runnable r2 = ((Supplier)() -> 1)::get; // allowed

Runnable interface defines the run method with return type void. In a lambda expression that means that the part following the arrow -> must be a statement. This is explained in JLS §15.27.3:

If the function type's result is void, the lambda body is either a statement expression (§14.8) or a void-compatible block.

JLS .5 clearly defines the syntax of a statement. As explained above it must be an "ExpressionStatement" (§ 14.8)。看那里,你会发现一个简单的文字不是一个合适的表达式,但是一个方法调用是(即使它 returns 东西)。

这对于 Lambdas 来说并不是真正的“特殊”规则。在语句上下文中使用 non-void 方法一直是可以接受的(在这种情况下,return 值被丢弃),但对于简单表达式则不然。例如“String.valueOf(true);”是一个有效的 java 语句,它可能单独占据一行,而“true;”不是,也可能不是。