4

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

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

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

有没有可能取消这个限制?

4

1 回答 1

5

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

s -> s.isEmpty()

可以分配给 ajava.util.function.Predicate或 a com.google.common.base.Predicate。出于这个原因,它无法访问java.util.function.Predicate的默认方法,直到它java.util.function.Predicate通过直接分配给 a 实际分配给 a 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类型,就可以调用它的方法。

于 2016-04-14T16:08:58.010 回答