如果变量在调试Java时在IntelliJ IDEA中具有名称"this $ 0",这意味着什么?

jhe*_*dus 10 java debugging intellij-idea

在此输入图像描述

我试图通过运行在调试模式下调用的测试来理解这个 Functional Reactive Java库,并在测试执行时逐步执行代码.testSendStream

上面的快照显示有一个名为奇怪命名的变量this$0.

这个名字来自哪里?

这个名字是什么意思?

为什么这个变量有这个名字?

给它这个名字背后的原因是什么?

当然这个名称不是来自代码本身,它是由IntelliJ或javac/java生成的.但为什么 ?

如果我用标签标记这个对象,看看会发生什么也很有趣Mystery Object.

在此输入图像描述

Psh*_*emo 13

this$0Inner类中的引用,它告诉我们使用哪个Outer类实例来创建Inner类的当前实例.

这是必要的,因为嵌套类可以访问外部类的所有成员(包括私有类),如果我们希望能够编写像Inner内部类一样的东西,JVM需要知道inner应该使用哪个实例来调用此方法(所以编译器将此代码更改为this$0).


更多细节和例子:

Outer outer = new Outer();
Outer.Inner inner = oc.new Outer.Inner(); 
Run Code Online (Sandbox Code Playgroud)

现在将在这里打印什么,为什么?

public class Outer {
    private int id;
    public Outer(int id) { this.id = id;}

    public class Inner{
        void printOuterID(){
            System.out.println(id); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们会看到

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();
Run Code Online (Sandbox Code Playgroud)

但是怎么Outer知道它应该打印outer来自methodFromOuterClass();而不是来自的价值Outer
这是因为内部类的每个实例都知道它创建的外部类的哪个实例.这是因为this$0.methodFromOuterClass()引用存储了用于创建内部实例的外部实例的引用.
此变量由编译器添加到所有非静态内部类,并在调用时设置其值

1
2
Run Code Online (Sandbox Code Playgroud)

所以代码就像

Outer.Inner in1 = o1.new Inner(); //`this$0` will be set to hold `o1` instance.
Run Code Online (Sandbox Code Playgroud)

基本上等于

void printOuterID(){
    System.out.println(id); 
}
Run Code Online (Sandbox Code Playgroud)