如果变量的名称为“this$0",这意味着什么?在 IntelliJ IDEA 中调试 Java? [英] What does it mean if a variable has the name "this$0" in IntelliJ IDEA while debugging Java?

查看:17
本文介绍了如果变量的名称为“this$0",这意味着什么?在 IntelliJ IDEA 中调试 Java?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过运行 test 在调试模式下调用 testSendStream 和在测试执行时逐步执行代码.

I am trying to understand this Functional Reactive Java library by running a test called testSendStream in debug mode and stepping through the code as the test executes.

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

The snapshot above shows that there is an oddly named variable called this$0.

这个名字从何而来?

这个名字是什么意思?

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

Why does this variable has this name ?

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

What is the reasoning behind giving it this name?

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

Surely this name does not come from the code itself, it is generated by IntelliJ or javac/java. But why ?

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

It is also interesting to see what happens if I mark this object by the label Mystery Object.

推荐答案

this$0Inner 类(非静态 嵌套类),用于保存对 Outer 类实例的引用,该实例用于创建 Inner 类的当前实例.

this$0 is "hidden field" in Inner class (the non-static nested class) which is used to hold reference to instance of Outer class which was used to create current instance of Inner class.

简而言之,当你有

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

inner 持有的

Inner 实例将在其 this$0 字段中存储对用于创建的 Outer 实例的引用它(与 outer 变量保持的引用相同).

Inner instance held by inner will store in its this$0 field reference to Outer instance used to create it (same reference as held by outer variable).

这是必要的,因为嵌套类必须能够访问外部类(包括私有类)的所有成员.如果我们希望能够在内部类中编写类似 methodFromOuterClass(); 的东西,JVM 需要知道它应该在哪个 Outer 实例上调用这个方法.为了使编译器可以将此类代码更改"为 this$0.methodFromOuterClass().

It is necessary because nested classes must have access to all members of outer classes (including private ones). If we want to be able to write something like methodFromOuterClass(); in inner class JVM needs to know on which Outer instance it should invoke this method. To make it possible compiler "changes" such code to 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); 
        }
    }
}

现在将在这里打印什么以及为什么?

Now what will be printed here and why?

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 引用存储了对用于创建内部实例的外部实例的引用.
该变量由编译器添加到所有非静态内部类中,并在调用时设置其值

but how in1 knew that it should print value of id from o1 and not from o2?
It is because each instance of inner class knows on which instance of outer class was it created. And that is because of this$0 reference which stores reference to outer instance used to create inner instance.
This variable is added to all non-static inner classes by compiler and its value is set when you invoke

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",这意味着什么?在 IntelliJ IDEA 中调试 Java?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆