由于Java8最近发布了,它全新的lambda表达式看起来真的很酷,我想知道这是否意味着我们所习惯的匿名类的消亡。
我对此进行了一些研究,发现了一些关于Lambda表达式如何系统地替换这些类的很酷的示例,例如Collection的sort方法,它用于获取一个匿名的比较器实例来执行排序:
Collections.sort(personList, new Comparator<Person>(){
public int compare(Person p1, Person p2){
return p1.firstName.compareTo(p2.firstName);
}
});
现在可以使用Lambdas来完成:
Collections.sort(personList, (Person p1, Person p2) -> p1.firstName.compareTo(p2.firstName));
而且看起来出奇的简洁。所以我的问题是,有没有理由继续在Java8中使用这些类而不是Lambda?
编辑
同样的问题,但在相反的方向上,使用Lambdas而不是匿名类有什么好处,因为Lambdas只能与单个方法接口一起使用,这个新功能只是在少数情况下使用的快捷方式,还是它真的很有用?
发布于 2014-03-26 00:21:13
匿名内部类(AIC)可用于创建抽象类或具体类的子类。AIC还可以提供接口的具体实现,包括添加状态(字段)。AIC的一个实例可以在它的方法体中使用this
来引用,因此可以在它上面调用更多的方法,它的状态可以随着时间的推移而变化,等等。
我猜想AICs的大多数用途是提供单个函数的无状态实现,因此可以用lambda表达式替换,但AICs的其他用途不能使用lambda。AIC将继续留在这里。
更新
AICs和lambda表达式之间的另一个区别是AICs引入了一个新的作用域。也就是说,名称是从AIC的超类和接口解析的,并且可以隐藏出现在词法封闭环境中的名称。对于lambda,所有名称都是按词法解析的。
发布于 2014-03-25 22:44:45
Lambdas虽然是一个很棒的特性,但它只适用于SAM类型。也就是说,接口只有一个抽象方法。一旦你的接口包含一个以上的抽象方法,它就会失败。这就是匿名类的用武之地。
所以,我们不能忽略匿名类。仅供参考,通过跳过p1
和p2
的类型声明,您的sort()
方法可以更简单
Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));
你也可以在这里使用方法引用。您可以在Person
类中添加一个compareByFirstName()
方法,并使用:
Collections.sort(personList, Person::compareByFirstName);
或者,为firstName
添加一个getter,直接从Comparator.comparing()
方法中获取Comparator
:
Collections.sort(personList, Comparator.comparing(Person::getFirstName));
发布于 2015-11-23 23:43:02
使用匿名类的Lambda性能
当应用程序启动时,必须加载和验证每个类文件。
匿名类由编译器作为给定类或接口的新子类型进行处理,因此将为每个类生成一个新的类文件。
Lambda在字节码生成上是不同的,它们更高效,使用JDK7附带的调用动态指令。
对于lambda,此指令用于延迟字节码中的lambda表达式的翻译,直到运行时。(指令仅在第一次调用时调用)
因此,Lambda表达式将成为一个静态方法(在运行时创建)。( stateles和statefull情况有一点不同,它们是通过生成的方法参数解决的)
https://stackoverflow.com/questions/22637900
复制相似问题