Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean if a variable has the name "this$0" in IntelliJ IDEA while debugging Java?

enter image description here

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.

enter image description here

like image 508
jhegedus Avatar asked Feb 11 '15 19:02

jhegedus


People also ask

What is this $0 in Java?

When the Enumerator needs to refer to the top or array fields of the enclosing instance, it indirects through a private link called this$0. The spelling of this name is a mandatory part of the transformation of inner classes to the Java 1.0 language, so that debuggers and similar tools can recognize such links easily.

How do I inspect a variable in debug mode IntelliJ?

IntelliJ IDEA allows you to inspect variables in a dedicated dialog. This is useful when you need to keep track of some variable (or the object whose reference it holds) and at the same time be able to navigate between frames and threads. Right-click a variable on the Variables tab and select Inspect.

What does debugging do in IntelliJ?

During a debugging session, you launch your program with the debugger attached to it. The purpose of the debugger is to interfere with the program execution and provide you with the information on what's happening under the hood. This facilitates the process of detecting and fixing bugs in your program.


2 Answers

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.

In short when you have

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

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).

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().


Little more details and example:

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();

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 printOuterID(){
    System.out.println(id); 
}

is essentially equal to

void printOuterID(){
    System.out.println(this$0.id); //although we can't access this$0 explicitly
}
like image 185
Pshemo Avatar answered Oct 12 '22 22:10

Pshemo


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.

like image 33
Amir Afghani Avatar answered Oct 13 '22 00:10

Amir Afghani