Java inner classes & inheritance: Is there a duplicate outer this reference?

Consider this scenario with inner classes and inheritance:

class X{
    class A{
       X foo(){
           return X.this; // outer this reference to X returned
       }
    }

}

class Y extends X{
    class B extends A {
       Y foo(){
           return Y.this; // outer this reference to Y returned
       }
    }
}

How does the memory layout of class B look like? Does it have two outer this references which both point to the same object? Or does it have only one outer this reference. What is the type of this reference?

The reason why I ask: I have a more or less deep hierarchy that uses nested classes like this. If the outer this reference was replicated for each level of inheritance, then I should maybe think over this design.

In addition, I am just curious about this design detail of the Java programming language.


I used javap to check the layout: The this pointer is really replicated

class X$A {
  final X this$0; // <-- first reference
  X$A(X);
  X foo();
}

class Y$B extends X$A {
  final Y this$0; // <-- second reference
  Y$B(Y);
  Y foo();
  X foo();
}
Jon Skeet
people
quotationmark

You can use javap to find out what fields a class has. (This is up to the compiler, not the JVM.) In this case:

C:\Users\Jon\Test>javap -p Y$B
Compiled from "Test.java"
class Y$B extends X$A {
  final Y this$0;
  Y$B(Y);
  Y foo();
  X foo();
}

So as you can see, there's one reference to an enclosing instance of Y - but X$A will also have a reference to the enclosing instance of X (which you can verify with javap -p X$A if you want). So yes, the object will have two fields in total for enclosing instances.

You can use javap -c Y$B to see the body of the constructor, which shows that the enclosing Y instance reference is then passed up to the constructor of X.A as the enclosing X instance reference - confirming that the two fields will have the same value.

However, I haven't yet found out where in the JLS this is addressed. In itself, this is a cause for concern - if you're in a situation which is hard to explain with the JLS, that's a pretty good hint that other developers may not be able to follow what's going on either. This feels like a convoluted design to me... unless you really need all these nested classes, I'd try to avoid them.

people

See more on this question at Stackoverflow