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.
The snapshot above shows that there is an oddly named variable called this$0
.
Where does this name come from ?
What does this name mean ?
Why does this variable has this name ?
What is the reasoning behind giving it this name?
Surely this name does not come from the code itself, it is generated by IntelliJ or javac/java. But why ?
It is also interesting to see what happens if I mark this object by the label Mystery Object
.
this$0
is reference in Inner
class which tells which instance of Outer
class was used to create current instance of Inner class.
It is necessary because since nested classes 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 which Outer
instance it should use to invoke this method on (so compiler changes this code to this$0.methodFromOuterClass()
).
Little more details and example:
public class Outer {
private int id;
public Outer(int id) { this.id = id;}
public class Inner{
void printParentID(){
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.printParentID();
in2.printParentID();
We will see
1
2
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.
So code like
void someMethod(){
System.out.println(id);
}
is essentially equal to
void someMethod(){
System.out.println(this$0.id);//although we can't access this$0 explicitly
}
The is a convention related to non static inner classes. The bytecode of the inner class will contain a reference to a package-scoped field named this$0
that allows you to refer to the this object of the enclosing class. Notice in your example this$0
is the same as the Mystery Object this
variable defined above it.