【问题标题】:What does it mean if a variable has the name "this$0" in IntelliJ IDEA while debugging Java?在调试 Java 时,如果 IntelliJ IDEA 中变量的名称为“this$0”,这意味着什么?
【发布时间】:2015-04-12 07:48:58
【问题描述】:

我试图通过在调试模式下运行名为testSendStreamtest 并在测试执行时逐步执行代码来了解this 功能响应式Java 库。

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

这个名字从何而来?

这个名字是什么意思?

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

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

这个名字肯定不是来自代码本身,它是由 IntelliJ 或者 javac/java 生成的。但为什么呢?

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

【问题讨论】:

    标签: java debugging intellij-idea


    【解决方案1】:

    this$0Inner 类(非静态嵌套类)中的“隐藏字段”,用于保存对 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
    }
    

    【讨论】:

      【解决方案2】:

      这是与非静态内部类相关的约定。内部类的字节码将包含对名为this$0 的包范围字段的引用,该字段允许您引用封闭类的 this 对象。请注意,在您的示例中 this$0 与上面定义的 Mystery Object this 变量相同。

      【讨论】:

      • 感谢您的帮助!
      猜你喜欢
      • 2020-07-12
      • 1970-01-01
      • 2012-10-08
      • 2020-06-29
      • 1970-01-01
      • 2011-02-17
      • 2022-12-12
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多