非静态内部类编译时自动添加隐式final字段this$0,指向外部类实例,由编译器在构造器首行初始化;该引用是访问外部类成员的基础,也是内存泄漏的根源。

非静态内部类在编译时会自动获得一个隐式的 final 引用字段,名字通常是 this$0,类型就是外部类。这个字段在内部类构造器执行的第一行就被初始化,指向创建它的那个外部类实例。
这个引用是怎么加进去的
你写代码时完全看不到 this$0,它是 javac 编译器悄悄生成的。只要内部类不是 static 的,编译器就会:
- 在内部类字节码中添加一个 package-private 的
final OuterClass this$0字段 - 修改内部类所有构造器签名,在参数列表开头加上
OuterClass outer - 在构造器第一行插入
this.this$0 = outer; - 所有对外部类私有成员的访问(比如
outerField),都会被转成this$0.outerField或通过合成方法调用
为什么需要它
这个引用是内部类能访问外部类实例成员的基础:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 没有它,内部类就无法拿到外部类的
this,也就不能调用外部类方法或读写其字段 - 即使外部类字段是
private,内部类也能访问——靠的是这个引用配合编译器生成的access$xxx合成方法 - 匿名内部类、局部内部类同样有
this$0,所以它们也持外部类引用,容易引发内存泄漏
它和 OuterClass.this 是什么关系
OuterClass.this 不是语法糖,而是直接读取这个隐式字段:
立即学习“Java免费学习笔记(深入)”;
- 写
OuterClass.this.doSomething(),等价于this$0.doSomething() - 写
OuterClass.this.field,底层就是this$0.field(或经由合成方法) - 它只在非静态内部类中合法;静态内部类没有
this$0,所以不允许用OuterClass.this
要注意的副作用
这个隐式引用是强引用,会导致外部类实例无法被回收:
- 如果内部类对象生命周期比外部类长(比如作为监听器注册到全局服务),外部类就被“锁住”
- Android 中 Activity 里定义 Handler 或 AsyncTask,常因此造成内存泄漏
- 若不需要访问外部类状态,优先考虑静态内部类或普通顶层类

















