Lambda 表达式通常不会改变您通常可以使用 Java 解决的问题集,但肯定会使解决某些问题变得更加容易,原因与此相同,我们不再使用汇编语言进行编程。从程序员的工作中删除多余的任务使生活更轻松,并允许做一些你甚至不会碰到的事情,只是为了你必须(手动)产生的代码量。
但 lambda 表达式不仅仅是在保存代码行。Lambda 表达式允许您定义函数,在此之前,您可以使用匿名内部类作为解决方法,这就是为什么在这些情况下您可以替换匿名内部类的原因,但通常不能。
最值得注意的是,lambda表达式是独立于它们将转换为的功能接口定义的,因此它们无法访问任何继承成员,此外,它们无法访问实现功能接口的类型实例。在 lambda 表达式中,并且与在周围的上下文中具有相同的含义,另请参阅此答案。此外,不能创建新的局部变量来隐藏周围上下文的局部变量。对于定义函数的预期任务,这消除了许多错误源,但这也意味着对于其他用例,可能存在无法转换为lambda表达式的匿名内部类,即使实现功能接口也是如此。this
super
此外,该构造保证生成一个新的不同实例(与往常一样)。匿名内部类实例始终保留在非上下文¹ 中创建的对其外部实例的引用。相反,lambda 表达式仅在需要时捕获对的引用,即如果它们访问或非成员。它们会生成有意未指定身份的实例,这允许实现在运行时决定是否重用现有实例(另请参阅“lambda 表达式是否在每次执行时都会在堆上创建对象?”)。new Type() { … }
new
static
this
this
static
这些差异适用于您的示例。您的匿名内部类构造将始终生成一个新实例,它也可能捕获对外部实例的引用,而您的是一个非捕获 lambda 表达式,在典型实现中计算结果为单一实例。此外,它不会在硬盘驱动器上生成文件。(Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())
.class
考虑到语义和性能方面的差异,lambda表达式可能会改变程序员将来解决某些问题的方式,当然,这也是由于新的API包含了利用新语言功能进行函数式编程的想法。另请参阅 Java 8 lambda 表达式和一等值。
¹ 从 JDK 1.1 到 JDK 17。从 JDK 18 开始,如果不使用外部实例,则内部类可能不会保留对外部实例的引用。出于兼容性原因,这要求内部类不可序列化。这仅适用于在 JDK 18 或更高版本下(重新)编译具有目标 JDK 18 或更高版本的内部类的情况。另请参阅 JDK-8271717