Java - Understanding the extra outer class parameter in an inner class constructor

[Updated: May 5, 2017, Created: Apr 28, 2017]

In Java, an inner class is defined relative to the outer class instance. The Java compiler automatically adds an extra private instance variable of the outer class to the inner class. That is the way, an inner class is linked to the enclosing class. This variable is initialized from an extra argument passed to the inner class constructor.

In following examples, we will, by reflection, analyze how the extra parameter is added to the inner class constructor.

public class MyClass {

    public static void main(String[] args) {
        printInnerClassConstructors(MyClass.class);
    }

    public static void printInnerClassConstructors(Class<?> myClass) {
        for (Class<?> c : myClass.getDeclaredClasses()) {
            System.out.printf("inner class: %s%n", c.getName());
            for (Constructor<?> constructor : c.getDeclaredConstructors()) {
                System.out.printf("Constructor: %s%n", constructor);
            }
        }
    }

     public class MyInnerClass {
    }
}

Output

inner class: com.logicbig.example.MyClass$MyInnerClass
Constructor: public com.logicbig.example.MyClass$MyInnerClass(com.logicbig.example.MyClass)

The above output shows the extra outer class parameter added to the inner class constructor.

User defined constructor parameters

What if we define our own parameters in the constructor? Let's try that out.

public class MyClass2 {

    public static void main(String[] args) {
        MyClass.printInnerClassConstructors(MyClass2.class);

        MyClass2 obj = new MyClass2();
        MyInnerClass obj2 = obj.new MyInnerClass("test", 2);
        System.out.println("instance: "+obj2);
    }

    public class MyInnerClass {
        public MyInnerClass(String a, int b) {
        }
    }
}

Output

inner class: com.logicbig.example.MyClass2$MyInnerClass
Constructor: public com.logicbig.example.MyClass2$MyInnerClass(com.logicbig.example.MyClass2,java.lang.String,int)
instance: com.logicbig.example.MyClass2$MyInnerClass@711c35a1

As seen in above output, the very first parameter is of the outer class, the rest are user defined ones.

Invoking inner class constructor by reflection

public class MyClass3 {

    public static void main(String[] args) throws Exception, InstantiationException {
        Constructor<MyInnerClass> c = MyInnerClass.class.getDeclaredConstructor(MyClass3.class);
        MyInnerClass obj = c.newInstance(new MyClass3());
        System.out.println("instance: "+obj);
    }

     public class MyInnerClass {
    }
}

Output

instance: com.logicbig.example.MyClass3$MyInnerClass@673116e9

Example Project

Dependencies and Technologies Used :

  • JDK 1.8
  • Maven 3.3.9

Inner Class Constructor Select All Download
  • inner-class-constructor
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also