Sai*_*Aye 10 java groovy lambda java-8
我了解了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"));
}
}
Run Code Online (Sandbox Code Playgroud)
这种风格与Groovy封闭非常相似.这是时髦的"HelloWorld"
def sayHello(name) {
println("Hello $name!")
}
def clos = {name -> sayHello(name)} clos.call('John Doe')
Run Code Online (Sandbox Code Playgroud)
我认为这两个代码之间的差异较小.是不是Java Lambda表达式与Groovy闭包的逻辑或风格类似?
小智 18
在Java 8(使用lambdas)或Groovy(使用闭包)中实现所谓的功能接口看起来完全相同,但底层机制却截然不同.我们以java.util.function.Consumer
功能界面为例.我们使用它forEach()
在一个java.util.List
名为的假设实例上调用新的Java 8 方法myList
.
在Java中它看起来像这样:
myList.forEach ((s) -> System.out.println(s));
Run Code Online (Sandbox Code Playgroud)
在Groovy中也是如此:
myList.forEach { s -> println s }
Run Code Online (Sandbox Code Playgroud)
两个编译器都从lambda/closure代码生成新的类.Java 8生成的类实现了目标接口(Consumer
在本例中),而不是从任何东西派生的,类似于嵌入式匿名类,如下所示:
myList.forEach(new Consumer<Object>() {
@Override
public void accept (Object s) {
System.out.println(s);
}
});
Run Code Online (Sandbox Code Playgroud)
相比之下,Groovy生成的内容看起来有点像下面这样:
myList.forEach (new Closure(this) {
void doCall(Object s) {
println s
}
}
Run Code Online (Sandbox Code Playgroud)
这将创建来源于一个匿名类groovy.lang.Closure
,它没有实现任何特定的接口.不过,它可以在这里用作参数.这是可能的,因为Groovy在运行时生成动态代理对象,实现"消费者"接口并转发对生成的Closure实例的任何调用.
因此,您可以通过Groovy闭包替换Java 8 lambdas,但不能反过来.如果要在Java 8代码中使用Groovy API,则无法调用期望具有lambda表达式的Closure的方法.Closure
不是一个功能接口而是一个抽象类,并且它不能由lambda表达式实现.
Java的lambda也是闭包。这些在抽象级别上是相同的功能,但是详细且取决于确切的版本,Groovy可能只是在创建临时实现类,而Java 8指定了一种完整的机制,包括lambda Metafactory,lambda factory和涉及以下内容的机制invokedynamic
获取lambda Metafactory。