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

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 = outer.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); 
  //OR
  //System.out.println(Outer.this.id);
}

is compiled into

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

BTW if your inner class doesn’t need to access non-static members of any of its outer classes you may change it to static class which will get rid of this$0 field.

Leave a Comment