Why do extensions of inner classes get duplicate outer class references?

Viewed 1434

I have the following Java file:

class Outer {
    class Inner { public int foo; }
    class InnerChild extends Inner {}
}

I compiled then disassembled the file using this command:

javac test.java && javap -p -c Outer Outer.Inner Outer.InnerChild

This is the output:

Compiled from "test.java"
class Outer {
  Outer();
    Code:
       0: aload_0
       1: invokespecial #1            // Method java/lang/Object."<init>":()V
       4: return
}
Compiled from "test.java"
class Outer$Inner {
  public int foo;

  final Outer this$0;

  Outer$Inner(Outer);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1            // Field this$0:LOuter;
       5: aload_0
       6: invokespecial #2            // Method java/lang/Object."<init>":()V
       9: return
}
Compiled from "test.java"
class Outer$InnerChild extends Outer$Inner {
  final Outer this$0;

  Outer$InnerChild(Outer);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1            // Field this$0:LOuter;
       5: aload_0
       6: aload_1
       7: invokespecial #2            // Method Outer$Inner."<init>":(LOuter;)V
      10: return
}

The first inner class has its this$0 field, pointing to the instance of Outer. That's fine. The second inner class, which extends the first, has a duplicate field of the same name, which it initializes before calling the super class's constructor with the same value.

The purpose of the int foo field above is just to confirm that inherited fields from the superclass do not show up in the javap output of a child class's dissassembly.

The first this$0 field is not private, so InnerChild should be able to use it. The extra field just seems to waste memory. (I first discovered it using a memory analysis tool.) What is its purpose and is there a way I can get rid of it?

2 Answers
Related