繁体   English   中英

Java Lambda 表达式是否类似于 Groovy 闭包的逻辑?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM