
匿名内部类适合在事件监听或多线程回调中快速实现接口的一次性定义,核心在于省去单独声明类的步骤,直接在需要接口实例的地方写出实现逻辑。
适用于单次使用的轻量回调
当某个接口只用一次(比如按钮点击、线程执行完后的通知),用匿名内部类最简洁。它自动继承或实现目标类型,无需命名、无需额外文件,代码紧凑且上下文清晰。
- 必须基于已有的接口或抽象类(如 Runnable、ActionListener、Callable)
- 语法结构为:new 接口名() { 方法实现 };
- 可访问外部方法的 final 或“事实 final”局部变量(Java 8+)
常见写法示例
多线程中启动一次性任务:
new Thread(new Runnable() {public void run() {
System.out.println("任务执行中");
}
}).start();
Swing 中绑定按钮点击事件:
button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "已点击");
}
});
Java 8 后推荐用 Lambda 替代(更简短),但匿名内部类仍适用需调用接口多个方法、或需显式 this 引用、或需在内部定义字段/方法等场景。
注意访问限制与生命周期
匿名内部类会隐式持有外部类实例的引用(非静态上下文下),可能导致内存泄漏——尤其在长生命周期对象(如 Activity、Service)中创建并传给后台线程或监听器时。
- 若外部类是 Activity,而匿名类被 Handler 或线程长期持有,Activity 无法被回收
- 解决方式:使用静态内部类 + WeakReference,或确保回调执行完及时解绑
- 避免在匿名类中直接修改外部方法的局部变量(只能读,且变量需事实 final)
和 Lambda 的关键区别
匿名内部类是完整类,可:
– 实现多个接口(通过多重继承抽象类间接实现)
– 声明构造代码块、字段、辅助方法
– 使用 this 指代自身,用 外部类名.this 明确访问外部实例
而 Lambda 只能实现函数式接口(仅一个抽象方法),无 this 分辨能力,也不能有状态。










