Java 在lambda表达式中使用默认方法

Java 在lambda表达式中使用默认方法,java,lambda,java-8,default-method,Java,Lambda,Java 8,Default Method,据我所知,lambda主体与周围的上下文具有相同的作用域,我想知道是否有特定的原因导致lambda实现的接口中的默认方法在主体中也不可用?这个限制是否能够实现一些优化,还是只是为了保持重载规则的简单 今天我正在原型化一些Java8API,当我遇到这个限制时,我非常失望,因为使用默认方法可以让我以一种非常优雅和非侵入性的方式实现该API 通过要求静态导入,实现相同的优雅或多或少是可能的,但这会导致“污染”名称空间 是否有可能取消此限制?默认方法对lambda不可用,因为在将lambda分配给函数类

据我所知,lambda主体与周围的上下文具有相同的作用域,我想知道是否有特定的原因导致lambda实现的接口中的默认方法在主体中也不可用?这个限制是否能够实现一些优化,还是只是为了保持重载规则的简单

今天我正在原型化一些Java8API,当我遇到这个限制时,我非常失望,因为使用默认方法可以让我以一种非常优雅和非侵入性的方式实现该API

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


是否有可能取消此限制?

默认方法对lambda不可用,因为在将lambda分配给函数类型之前,尚未为其指定类型。例如,lambda

s -> s.isEmpty()
可以分配给
java.util.function.Predicate
com.google.common.base.Predicate
。由于这个原因,它无法访问
java.util.function.Predicate
的默认方法,除非它通过直接赋值给
java.util.function.Predicate
将lambda作为
java.util.function.Predicate
参数传递给
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
((谓词)s->s.isEmpty()).negate();//否定是谓词的默认方法

考虑它的一种方式是类似于装箱一个
int
Integer
的方法不能对文本整数值进行调用,但一旦将整数值分配给
Integer
类型,就可以调用其方法。

一个简短的示例将有助于理解您所说的相关(尽管不是重复的):“lambda主体与周围上下文具有相同的作用域”已经暗示范围中没有虚假的
默认方法。当然,这大大简化了名称解析规则。这一切都可以归结为“lambda表达式不是内部类的语法糖”…请看,相关的问题实际上包含了一个很好的例子。我不明白这是什么原因。我不知道编译器是如何实现的,但由于lambda类型是从LHS推断出来的,所以编译器在检查lambda主体时应该已经知道了类型。我明白你的意思,我不打算为编译器设计辩护。我的理解是,FWIW,lambda是一个没有签名的体,而函数接口是一个没有体的签名,直到赋值或强制转换,两者才连接起来并生成实际的函数。希望有帮助。