this$0 是 Inner 类(非静态嵌套类)中的“隐藏字段”,用于保存对 Outer 类实例的引用,该类用于创建当前内部类的实例。
总之,当你有
Outer outer = new Outer();
Outer.Inner inner = oc.new Outer.Inner();
inner 持有的Inner 实例将在其this$0 字段中存储对用于创建它的Outer 实例的引用(与outer 变量持有的引用相同)。
这是必要的,因为嵌套类必须可以访问外部类的所有成员(包括私有成员)。如果我们希望能够在内部类中编写类似methodFromOuterClass(); 的内容,JVM 需要知道它应该在哪个Outer 实例上调用此方法。为了使编译器能够将此类代码“更改”为this$0.methodFromOuterClass()。
更多细节和例子:
public class Outer {
private int id;
public Outer(int id) { this.id = id;}
public class Inner{
void printOuterID(){
System.out.println(id);
}
}
}
现在这里将打印什么以及为什么?
Outer o1 = new Outer(1);
Outer o2 = new Outer(2);
Outer.Inner in1 = o1.new Inner();
Outer.Inner in2 = o2.new Inner();
in1.printOuterID();
in2.printOuterID();
我们会看到
1
2
但是in1 怎么知道它应该从o1 而不是从o2 打印id 的值?
这是因为内部类的每个实例都知道它是在哪个外部类实例上创建的。这是因为 this$0 引用存储了对用于创建内部实例的外部实例的引用。
该变量由编译器添加到所有非静态内部类中,并在您调用时设置其值
Outer.Inner in1 = o1.new Inner(); //`this$0` will be set to hold `o1` instance.
这样的代码
void printOuterID(){
System.out.println(id);
}
本质上等于
void printOuterID(){
System.out.println(this$0.id); //although we can't access this$0 explicitly
}