From e40dfe1c9ff019051d0e0a99101be3ad57f2809f Mon Sep 17 00:00:00 2001 From: sjsdfg <736777445@qq.com> Date: Wed, 3 Apr 2019 20:40:36 +0800 Subject: [PATCH] =?UTF-8?q?42.=20lambda=20=E8=A1=A8=E8=BE=BE=E5=BC=8F?= =?UTF-8?q?=E4=BC=98=E4=BA=8E=E5=8C=BF=E5=90=8D=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/notes/42. lambda表达式优于匿名类.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/notes/42. lambda表达式优于匿名类.md b/docs/notes/42. lambda表达式优于匿名类.md index 831ff90..a152379 100644 --- a/docs/notes/42. lambda表达式优于匿名类.md +++ b/docs/notes/42. lambda表达式优于匿名类.md @@ -96,13 +96,13 @@ public enum Operation { ```   请注意,我们使用表示枚举常量行为的 **lambdas** 的 `DoubleBinaryOperator` 接口。 这是 `java.util.function` 中许多预定义的函数接口之一(条目 44)。 它表示一个函数,它接受两个 **double** 类型参数并返回 **double** 类型的结果。 - +   看看基于 **lambda** 的 `Operation` 枚举,你可能会认为常量特定的方法体已经失去了它们的用处,但事实并非如此。 与方法和类不同,**lambda 没有名称和文档; 如果计算不是自解释的,或者超过几行,则不要将其放入 lambda 表达式中。** 一行代码对于 **lambda** 说是理想的,三行代码是合理的最大值。 如果违反这一规定,可能会严重损害程序的可读性。 如果一个 **lambda** 很长或很难阅读,要么找到一种方法来简化它或重构你的程序来消除它。 此外,传递给枚举构造方法的参数在静态上下文中进行评估。 因此,枚举构造方法中的 **lambda** 表达式不能访问枚举的实例成员。 如果枚举类型具有难以理解的常量特定行为,无法在几行内实现,或者需要访问实例属性或方法,那么常量特定的类主体仍然是行之有效的方法。 - +   同样,你可能会认为匿名类在 **lambda** 时代已经过时了。 这更接近事实,但有些事情你可以用匿名类来做,而却不能用 **lambdas** 做。 **Lambda** 仅限于函数式接口。 如果你想创建一个抽象类的实例,你可以使用匿名类来实现,但不能使用 **lambda**。 同样,你可以使用匿名类来创建具有多个抽象方法的接口实例。 最后,**lambda** 不能获得对自身的引用。 在 **lambda** 中,`this` 关键字引用封闭实例,这通常是你想要的。 在匿名类中,`this` 关键字引用匿名类实例。 如果你需要从其内部访问函数对象,则必须使用匿名类。 - +   **Lambdas** 与匿名类共享无法可靠地序列化和反序列化实现的属性。**因此,应该很少 (如果有的话) 序列化一个 lambda(或一个匿名类实例)。** 如果有一个想要进行序列化的函数对象,比如一个 `Comparator`,那么使用一个私有静态嵌套类的实例(条目 24)。 - +   综上所述,从 Java 8 开始,**lambda** 是迄今为止表示小函数对象的最佳方式。 **除非必须创建非函数式接口类型的实例,否则不要使用匿名类作为函数对象。** 另外,请记住,**lambda** 表达式使代表小函数对象变得如此简单,以至于它为功能性编程技术打开了一扇门,这些技术在 Java 中以前并不实用。