静态内部类是最直接有效的手段,因其不生成this$0字段、与外部类生命周期解耦;若必须用非静态类,则需配合显式传参、weakreference和主动清理。

核心是切断非静态内部类对外部类实例的隐式强引用链。静态内部类天然不持 this$0,是最直接有效的手段;若必须用非静态类,则需配合显式传参、WeakReference 和主动清理。
优先改用静态内部类
非静态内部类编译后会自动生成 this$0 字段,强引用外部类实例。静态内部类没有该字段,字节码上就是一个独立类(如 Outer$StaticTask.class),生命周期完全解耦。
- 把
class Inner implements Runnable改为static class Inner implements Runnable - 它不能访问外部类的非静态成员——这不是缺陷,而是 JVM 层面的防护设计
- 仍可安全调用外部类的
static字段和方法,无需额外处理
需要数据时,只传必要值,不传 this
静态内部类虽独立,但常需少量外部状态。关键在于避免“传整个对象”,只传递真正需要的具体值或接口。
- 传具体参数:如
new StaticTask(userId, timeout, token),而非new StaticTask(this) - 传回调接口:定义
interface OnResultListener { void onSuccess(String data); },由外部类实现后传入 - 避免传 UI 组件(如 Activity、View)或其子类实例,它们本身生命周期短且强绑定
必须访问外部实例时,用 WeakReference + 每次判空
当静态内部类确实要更新 UI 或调用实例方法,且无法保证执行时机在外部类存活期内,WeakReference 是安全兜底方式。
- 构造时传入:
private final WeakReference<activity> activityRef = new WeakReference(activity);</activity> - 每次使用前必须判空:
Activity act = activityRef.get(); if (act != null && !act.isFinishing()) { ... } - 切忌在判空后缓存
act的强引用,否则等于白加
长生命周期容器中必须手动清理
即使用了静态内部类 + WeakReference,只要它注册进了 Handler、EventBus、广播接收器或线程池,就仍需在外部类销毁时主动解除绑定。
- Android 中,在
Activity.onDestroy()或Fragment.onDetach()里调用handler.removeCallbacksAndMessages(null) - 广播接收器要配对调用
unregisterReceiver() - 线程池任务保留
Future,任务结束前调用future.cancel(true) - 自定义监听器提供
unregister()方法,并确保业务侧调用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











