繁体   English   中英

在调试Java时,如果变量在IntelliJ IDEA中名称为“ this $ 0”,那意味着什么?

[英]What does it mean if a variable has the name “this$0” in IntelliJ IDEA while debugging Java?

在此处输入图片说明

我试图通过在调试模式下运行一个称为testSendStream测试并逐步执行该测试的代码来理解功能性Java testSendStream库。

上面的快照显示了一个名为this$0的奇怪变量。

这个名字从哪里来?

这个名字是什么意思?

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

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

当然,该名称并非来自代码本身,它是由IntelliJ或javac / java生成的。 但为什么 ?

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

在此处输入图片说明

this$0Inner类( 非静态嵌套类)中的“隐藏字段”,用于保存对Outer类实例的引用,该实例用于创建Inner类的当前实例。

简而言之,当你有

Outer outer = new Outer();
Outer.Inner inner = oc.new Outer.Inner(); 

Inner所保持的实例inner其将存储this$0字段参照Outer使用(由为持有相同的附图来创建它实例outer变量)。

这是必需的,因为嵌套类必须有权访问外部类的所有成员(包括私有成员)。 如果我们想写类似methodFromOuterClass();东西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
}

是与非静态内部类有关的约定。 内部类的字节码将包含对名为this$0的包作用域的引用,该字段使您可以引用封闭类的this对象。 注意,在您的示例中, this$0Mystery Object this变量在其上Mystery Object this的相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM