[英]Is Java Lambda expression is similar logic of Groovy closure?
我正在学习 Java 8 新功能Lambda 表达式。 这是我使用 Lambda 表达式的“HelloWorld”类
public class LambdaHelloWorld {
interface HelloWorld {
String sayHello(String name);
}
public static void main(String[] args) {
HelloWorld helloWorld = (String name) -> { return "Hello " + name; };
System.out.println(helloWorld.sayHello("John Doe"));
}
}
这种风格与 Groovy 闭包非常相似。 这是时髦的“HelloWorld”
def sayHello(name) {
println("Hello $name!")
}
def clos = {name -> sayHello(name)}
clos.call('John Doe')
我认为这两个代码彼此之间的差异较小。Java Lambda表达式是否类似于Groovy闭包的逻辑或风格?
在 Java 8(使用 lambdas)或 Groovy(使用闭包)中实现所谓的函数式接口看起来完全相同,但底层机制却大不相同。 我们以java.util.function.Consumer
函数式接口为例。 我们使用它在名为myList
的假设java.util.List
实例上调用新的 Java 8 forEach()
方法。
在 Java 中,它看起来像这样:
myList.forEach ((s) -> System.out.println(s));
在 Groovy 中也是如此:
myList.forEach { s -> println s }
两个编译器都从 lambda / 闭包代码生成新类。 Java 8 生成的类实现了目标接口(在本例中为Consumer
),不是从任何东西派生出来的,类似于这样的嵌入式匿名类:
myList.forEach(new Consumer<Object>() {
@Override
public void accept (Object s) {
System.out.println(s);
}
});
相比之下,Groovy 生成的内容看起来有点像以下内容:
myList.forEach (new Closure(this) {
void doCall(Object s) {
println s
}
}
这将创建一个从groovy.lang.Closure
派生的匿名类,它没有实现任何特定的接口。 尽管如此,它可以在这里用作参数。 这是可能的,因为 Groovy 在运行时生成动态代理对象,实现“Consumer”接口并将任何调用转发到生成的 Closure 实例。
因此,您可以用 Groovy 闭包替换 Java 8 lambdas,但不能反过来。 当您想在 Java 8 代码中使用 Groovy API 时,您不能使用 lambda 表达式调用需要闭包的方法。 Closure
不是函数式接口,而是抽象类,并且它不能由 lambda 表达式实现。
Java 的 lambdas 也是闭包。 这些在抽象层面上是相同的特性,但在细节上并取决于确切的版本,Groovy 可能只是创建临时实现类,而 Java 8 指定了一个完整的机制,由 lambda Metafactory、lambda factory 和一个机制组成invokedynamic
获取拉姆达Metafactory。
我想要一个简单的本地闭包来传递/执行。 我从来没有在任何地方找到这个答案,所以添加我的自旋,这样你就可以看到从本地 groovy 闭包到本地 java lambda 的实际映射。
常规:
def clos = {name -> sayHello(name)}
clos('John Doe')
爪哇:
Consumer<String> clos = name -> sayHello(name);
clos.accept("John Doe");
关键是带有要调用的 accept() 方法的血腥消费者接口 - 您必须根据它们的预装函数接口 (java.util.function.*) 匹配 Java lambda 的参数和返回类型。 与无类型的 Groovy 版本相比,这一点是一个阻力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.