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

标签 java debugging intellij-idea

enter image description here

我正在努力理解 this通过运行 test 来实现功能性 Reactive Java 库在 Debug模式下调用 testSendStream 并在测试执行时单步执行代码。

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

这个名字从何而来?

这个名字是什么意思?

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

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

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

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

enter image description here

最佳答案

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

简而言之,当你有

Outer outer = new Outer();
Outer.Inner inner = outer.new Outer.Inner(); 
inner 持有的

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

这是必要的,因为嵌套类必须能够访问外部类的所有成员(包括私有(private)成员)。如果我们希望能够在内部类中编写类似 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 的值?< br/> 这是因为内部类的每个实例都知道它是在哪个外部类实例上创建的。这是因为 this$0 引用存储了对用于创建内部实例的外部实例的引用。
此变量由编译器添加到所有非静态内部类,并在您调用时设置其值

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

这样的代码

void printOuterID(){
    System.out.println(id); 
  //OR
  //System.out.println(Outer.this.id);
}

编译成

void printOuterID(){
    System.out.println(this$0.id); //although we can't access this$0 explicitly
}

顺便说一句,如果您的内部类不需要访问其任何外部类的非静态成员,您可以将其更改为 static class 这将摆脱 this$0 字段。

关于java - 调试 Java 时,如果在 IntelliJ IDEA 中变量的名称为 "this$0",这意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28462849/

相关文章:

java - Eclipse:如何/在何处将文本文件包含在 Java 项目中?

java - 在 JFileChooser 中仅显示 TSTA* 文件

java - 错误 : 'Please fix the version conflict either by updating the version....'

c++ - 当前不会命中断点。在 vc++(Visual Studio 2013) 中尚未加载此文档的任何符号

android - IntelliJ Idea - Android 虚拟设备无法启动

java - 在 IntelliJ 中附加 .java 文件作为 .jar 的源?

java - 设置 RGB 值以减少 PNG 图像中的调色板

c++ - 无论我尝试了什么,GDB 都无法在我的 Mac (Mojave) 上运行。常见错误,但我找不到解决方案

debugging - 为什么 .net 中的对象引用错误异常不告诉我哪个对象为空?

scala - 如何附加 Scala Intellij 调试器进行测试?