匿名内部类与Lambda表达式知识点总结
匿名内部类
基本概念
- 匿名内部类是没有名字的内部类
- 用于快速创建某个类或接口的子类/实现类的实例
- 适合只使用一次的类实现
语法结构
java
1 | new 父类构造器(参数列表) | 实现接口() { |
特点
- 必须继承一个父类或实现一个接口
- 只能创建一个实例
- 没有构造方法(但可以有实例初始化块)
- 可以访问外部类的成员,包括私有成员
- 如果访问局部变量,该变量必须是final或事实上final的
使用场景
- 事件监听器
- 线程实现
- 需要快速实现某个接口或抽象类
Lambda表达式
基本概念
- Java 8引入的函数式编程特性
- 用于简化函数式接口的实现
- 本质是一个匿名函数
语法结构
java
1 | (parameters) -> expression |
特点
- 只能用于函数式接口(只有一个抽象方法的接口)
- 类型可以自动推断
- 可以访问外部final或事实上final的局部变量
- 简洁明了,减少样板代码
常见函数式接口
Runnable
->() -> {...}
Consumer<T>
->(T t) -> {...}
Supplier<T>
->() -> {...}
Function<T,R>
->(T t) -> {... return R;}
Predicate<T>
->(T t) -> {... return boolean;}
匿名内部类 vs Lambda表达式
特性 | 匿名内部类 | Lambda表达式 |
---|---|---|
语法复杂度 | 较复杂 | 简洁 |
使用场景 | 任何类/接口 | 仅函数式接口 |
this关键字 | 指向匿名内部类本身 | 指向外部类 |
编译后 | 生成单独的.class文件 | 不生成.class文件,使用invokedynamic |
访问外部变量 | 必须final或事实上final | 必须final或事实上final |
多重方法 | 可以 | 不可以 |
示例代码
匿名内部类示例
java
1 | // 实现接口 |
Lambda表达式示例
java
1 | // 无参数 |
注意事项
- Lambda表达式只能替代函数式接口的匿名内部类
- 当需要重写多个方法时,仍需使用匿名内部类
- Lambda表达式中的变量必须是final或事实上final
- 在需要访问实例变量或方法时,匿名内部类可能更合适