Java8 Lambdas vs Anonymous classes

2022-08-31 08:53:36

由于Java8最近已经发布,并且其全新的lambda表达式看起来非常酷,我想知道这是否意味着我们习惯的Anonymous类的消亡。

我一直在对此进行一些研究,并发现了一些关于Lambda表达式将如何系统地替换这些类的很酷的例子,例如Collection的排序方法,该方法用于获取比较器的匿名实例来执行排序:

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中使用这些类而不是Lambdas?

编辑

同样的问题,但方向相反,使用Lambda而不是匿名类有什么好处,因为Lambda只能与单方法接口一起使用,这个新功能只是一个只在少数情况下使用的快捷方式,还是真的有用?


答案 1

匿名内部类 (AIC) 可用于创建抽象类或具体类的子类。AIC还可以提供接口的具体实现,包括添加状态(字段)。AIC的实例可以在其方法体中使用,因此可以在其上调用其他方法,其状态可以随着时间的推移而改变,等等。这些都不适用于 lambdas。this

我猜AIC的大多数用途是提供单个函数的无状态实现,因此可以用lambda表达式替换,但是AICs还有其他用途不能使用lambda。AIC将继续存在。

更新

AIC 和 lambda 表达式之间的另一个区别是 AIC 引入了新的范围。也就是说,名称是从 AIC 的超类和接口解析而来的,并且可以隐藏在词法封闭环境中出现的名称。对于 lambda,所有名称都按词法解析。


答案 2

Lambdas 虽然是一个很棒的功能,但只能与 SAM 类型一起使用。也就是说,仅使用单个抽象方法的接口。一旦您的接口包含多个抽象方法,它就会失败。这就是匿名类有用的地方。

所以,不,我们不能忽略匿名类。仅供参考,您的方法可以更简化,通过跳过 和 的类型声明:sort()p1p2

Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));

您也可以在此处使用方法参考。您可以在类中添加一个方法,并使用:compareByFirstName()Person

Collections.sort(personList, Person::compareByFirstName);

或者,添加一个 getter for ,直接获取 from Comparator.comparing() 方法:firstNameComparator

Collections.sort(personList, Comparator.comparing(Person::getFirstName));

推荐