匿名类默认持有外部类强引用易致内存泄漏,应优先用静态内部类、显式传参、WeakReference及及时清理。

匿名类在 Java 中默认持有外部类的强引用(编译后生成 this$0 字段),一旦它被长期持有——比如提交到线程池、注册为监听器、缓存在静态容器中——就会阻止外部类实例被垃圾回收,尤其在 Android 中容易导致 Activity 或 Fragment 泄漏。
关键不是禁用匿名类,而是控制这条隐式引用链的生命周期和强度。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
优先改用静态内部类
如果逻辑不依赖外部类的实例字段或方法,就该用 `static class` 替代匿名类。它没有 `this$0`,天然解耦,字节码上就是独立类。 - 适合场景:数据解析、定时任务封装、工具型 Runnable/Callable - 注意:仍可访问外部类的 `static` 成员,无需额外处理 - 示例:把 `new Runnable() { ... }` 换成 `new StaticTask(userId, timeout)`,通过构造参数传值,不传 `this`显式传参,避免隐式捕获
只需几个字段?那就提前提取为 `final` 局部变量,在匿名类里只用这些值。 - 编译器不会为 `final String id = this.userId;` 生成 `this$0` - 不要写 `new Runnable() { void run() { outer.doSomething(); } }`,而应写 `final Consumer callback = result -> updateUI(result);`必须持实例时用 WeakReference 包装
当确实要调用外部类的实例方法(如更新 UI、释放资源),且无法保证调用时机在外部类存活期内: - 在外部类中声明 `private final WeakReference长生命周期场景必须主动清理
即使用了 `WeakReference`,只要匿名类被注册进全局对象(如静态 Handler、EventBus、广播接收器、线程池),就得手动解绑: - Android 中,在 `onDestroy()` 或 `onCleared()` 里调用 `handler.removeCallbacksAndMessages(null)` - 给监听器保留引用(如 `private OnClickListener listener;`),销毁时设为 `null` 并解除注册 - 提交到线程池的任务,若涉及上下文,考虑用 `future.cancel(true)` 中断执行不复杂但容易忽略。

















