【问题标题】:Lambda casting rulesLambda 转换规则
【发布时间】:2016-08-10 07:55:42
【问题描述】:

我很好奇为什么不能将具有返回类型的 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

【问题讨论】:

    标签: java lambda runnable


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      Runnable 接口定义了返回类型为 void 的 run 方法。在 lambda 表达式中,这意味着箭头 -> 后面的部分必须是一个语句。这在JLS §15.27.3中有解释:

      如果函数类型的结果是 void,则 lambda 主体是语句表达式(第 14.8 节)或 void 兼容块。

      JLS $14.5 清楚地定义了语句的语法。如上所述,它必须是“ExpressionStatement”(§ 14.8)。看看那里,你会发现一个简单的字面量不是一个合适的表达式,但是一个方法调用是(即使它返回了一些东西)。

      【讨论】:

      • 您能否指出 JLS 中提到的地方,在这种情况下,“箭头-> 后面的部分必须是语句”?我正在寻找它。
      • @Tunaki 找到了,它是§15.27.3
      • @RealSkeptic 确实完美:如果函数类型的结果为 void,则 lambda 主体要么是语句表达式(第 14.8 节),要么是与 void 兼容的块。主表达式不是语句表达式(也不是块)。
      • @RealSkeptic 哇。感谢您发现它。我会将此信息添加到我的答案中(在您同意的情况下)。
      猜你喜欢
      • 2013-04-10
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多