【问题标题】:Using default methods in lambda expression在 lambda 表达式中使用默认方法
【发布时间】:2016-08-06 07:19:43
【问题描述】:

根据JLS 15.27.2,lambda 主体与周围上下文具有相同的范围,我想知道是否有特定原因导致 lambda 实现的接口中的默认方法在身体也是?此限制是否启用了一些优化,还是只是为了保持重载规则简单?

我今天正在对一些 Java 8 API 进行原型设计,当我遇到这个限制时,我感到非常失望,因为使用默认方法可以让我以一种非常优雅且非侵入性的方式实现该 API。

要求静态导入或多或少有可能实现相同的优雅,但这会导致“污染”命名空间。

有没有可能解除这个限制?

【问题讨论】:

标签: java lambda java-8 default-method


【解决方案1】:

默认方法对 lambda 不可用,因为 lambda 在分配给函数类型之前尚未被赋予类型。例如,lambda

s -> s.isEmpty()

可以分配给java.util.function.Predicatecom.google.common.base.Predicate。出于这个原因,它无法访问java.util.function.Predicate 的默认方法,直到它通过直接分配给java.util.function.Predicate 实际分配给java.util.function.Predicate,通过将lambda 作为java.util.function.Predicate 参数传递,从返回类型为java.util.function.Predicate 的函数,或者简单地将其转换为java.util.function.Predicate,如下所示:

((Predicate<String>) s -> s.isEmpty()).negate();   // negate is a default method on Predicate

一种思考方式类似于对int 值进行装箱。 Integer 的方法不能在字面整数值上调用,但是一旦将整数值分配给 Integer 类型,就可以调用它的方法。

【讨论】:

  • 嗯,我不明白这是什么原因。我不知道编译器是如何实现的,但是由于 lambda 类型是从 LHS 推断出来的,所以编译器在检查 lambda 主体时应该已经知道该类型。
  • 我明白你的意思,我不打算为编译器设计辩护。我的理解,FWIW,lambda 是一个没有签名的主体,而功能接口是一个没有主体的签名,直到分配或强制转换两者才连接起来并生成一个实际的函数。希望对您有所帮助。
猜你喜欢
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
  • 2016-10-05
  • 1970-01-01
相关资源
最近更新 更多