如果变量的名称为“this$0",这意味着什么?在 IntelliJ IDEA 中调试 Java? [英] What does it mean if a variable has the name "this$0" in IntelliJ IDEA while debugging 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$0
是 Inner
类(非静态 嵌套类),用于保存对 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屋!