匿名内部类是Java中无需命名、直接在new后定义并实例化的类,须基于接口或抽象类,编译生成独立class文件,可访问final或事实final局部变量,适用于单次使用的场景,但需注意内存泄漏与性能问题。

Java 中匿名内部类是在 new 关键字后面直接定义并实例化一个类,**不需要显式声明类名**,常用于简化只用一次的接口实现或抽象类子类。
语法结构:new 接口名/抽象类名() { ... }
匿名内部类必须基于一个已存在的类型(接口或抽象类)来创建。它本质上是该类型的子类(对接口而言是实现类),编译时会自动生成一个带编号的类(如 OuterClass$1.class)。
- 如果基于接口:必须实现接口中所有抽象方法
- 如果基于抽象类:必须实现其中所有未实现的抽象方法
- 不能定义构造器,但可以有初始化块或实例变量
- 可访问所在作用域的 final 或“事实 final”(Java 8+)的局部变量
常见写法示例
比如启动一个线程:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello from anonymous class");
}
}).start();
Java 8 后更常用 Lambda,但匿名类仍适用于需多个方法、需持有所在类引用、或需继承具体类等场景。
立即学习“Java免费学习笔记(深入)”;
注意事项
匿名内部类不是语法糖,它会产生独立的 .class 文件,并持有对外部类 this 的隐式引用(可能导致内存泄漏)。
- 避免在静态上下文中引用非静态外部成员
- 不要在循环里反复创建大量匿名类实例(影响性能和 GC)
- 逻辑复杂时建议提取为命名类,提升可读性和复用性
与 Lambda 的区别
Lambda 只能用于函数式接口(仅一个抽象方法),而匿名内部类可用于任意接口或抽象类;Lambda 不生成新类文件,也不持有外部类引用(除非用到 this 或实例变量)。
当需要重写多个方法、调用父类方法、或扩展某个具体类时,只能用匿名内部类。


















