6.8.4 Lambda表达式与匿名内部类的联系和区别

6.8.4 Lambda表达式与匿名内部类的联系和区别

Lambda表达式是匿名内部类的一种简化,因此它可以部分取代匿名内部类的作用, Lambda表达式与匿名内部类存在如下相同点。

  • Lambda表达式与匿名内部类一样,都可以直接访问"effectively final"的局部变量,以及外部类的成员变量(包括实例变量和类变量)
  • Lambda表达式创建的对象与匿名内部类生成的对象一样,都可以直接调用从接口中继承的默认方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@FunctionalInterface
interface Displayable {
// 定义一个抽象方法
void display();

// 定义一个默认方法
default int add(int a, int b) {
return a + b;
}

}

public class LambdaAndinner {
// 实例变量
private int age = 12;
// 类变量
private static String name = "Hello";

public void test() {
// 方法局部变量
String book = "World";
// final String book = "World";
// 创建函数式接口实例,通过Lambda表达式实现display方法
Displayable displayable = () -> {
// Lambda表达式中不可以修改局部变量的值
// book = "被局部内部类访问的局部变量 只能赋值一次";
System.out.println("当前方法 局部变量 book=" + book);
System.out.println("外部类 类变量 name=" + name);
System.out.println("外部类 实例变量 age=" + age);
// Lambda表达式代码体中不允许调用接口默认方法
// System.out.println(add(1,2));
};
// 调用实现的display方法
displayable.display();
// 调用从接口中继承得到的add方法
displayable.add(3, 5);
}

public static void main(String[] args) {
LambdaAndinner lambdaAndinner = new LambdaAndinner();
lambdaAndinner.test();
}
}
  • Lambda表达式的代码块与匿名内部类的方法体是相同的。
  • 与匿名内部类相似的是,由于Lambda表达式访问了book局部变量,因此该局部变量相当于有隐式的final修饰,因此同样不允许对book局部变量重新赋值。
  • 程序使用Lambda表达式创建的对象不仅可调用接口中唯一的抽象方法,也可调用接口中的默认方法。

Lambda表达式和匿名内部类的区别

Lambda表达式与匿名内部类主要存在如下区别。

  1. 匿名内部类可以为任意接口创建实例,不管接口包含多少个抽象方法,只要匿名内部类实现所有的抽象方法即可;但**Lambda表达式只能为函数式接口创建实例**
  2. 匿名内部类可以为抽象类甚至普通类创建实例;但Lambda表达式只能为函数式接口创建实例。
  3. 匿名内部类实现的抽象方法的方法体中允许调用接口中定义的默认方法;但Lambda表达式的代码块中不允许调用接口中定义的默认方法。