匿名内部类是java中无类名、仅用一次的局部内部类,用于简化接口实现或类继承;语法为new 父类(){}或new 接口(){},必须重写抽象方法,可访问外部final或事实final变量,编译生成outer$1.class文件。

匿名内部类是 Java 中一种没有名字的内部类,通常用于简化代码,尤其在需要快速实现接口或继承抽象类的场景下。它必须基于某个类或接口创建,且只能用一次。
匿名内部类的基本写法
匿名内部类的语法结构为:new 父类构造器(实参列表) 或 new 接口() { // 类体 }。注意它没有类名、不能有构造方法、不能被 public/private/protected 修饰,也不能定义静态成员(除静态常量外)。
- 实现接口时,必须实现接口中所有抽象方法
- 继承类时,只能继承一个具体类或抽象类,且要满足构造器可访问
- 可以访问所在方法的 final 局部变量(Java 8 后放宽为“事实上的 final”,即未被重新赋值)
常见使用场景举例
最典型的是事件监听、线程启动、集合排序等需要一次性实现接口的地方。
- Swing/AWT 中添加按钮点击监听:button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("clicked"); } });
- 创建并启动线程:new Thread(new Runnable() { public void run() { System.out.println("running"); } }).start();
- 使用 Lambda 替代(Java 8+):button.addActionListener(e -> System.out.println("clicked")); —— 功能相同,更简洁
匿名内部类的注意事项
虽然写法方便,但过度使用会影响可读性和调试。需注意以下几点:
- 无法重复使用,每次 new 都是一个新类,JVM 会为其生成类似 OuterClass$1.class 的字节码文件
- 不能有显式构造器,但可通过实例初始化块模拟初始化逻辑
- 若需访问外部方法的局部变量,该变量必须是 final 或事实 final
- 与 Lambda 表达式不同,匿名内部类可以有多个抽象方法(适合非函数式接口),也能定义自己的字段和方法
与 Lambda 表达式的区别
当目标类型是函数式接口(仅含一个抽象方法)时,Lambda 是匿名内部类的更优替代。
- Lambda 更简洁、性能略好(不生成额外 class 文件)、支持变量捕获更灵活
- 匿名内部类能持有对外部类 this 的引用,可能引发内存泄漏;Lambda 在无外部变量引用时不会持有 this
- 若需重用逻辑、或接口方法不止一个、或需要额外状态字段,仍需用匿名内部类甚至独立类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











