Close

Java - Implicit Outer Class reference in Inner classes

[Last Updated: Apr 25, 2018]

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.

Example

In this example by using reflection, we are going to see how the extract constructor parameter and the instance field of the other class is added to the inner class.

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);
            }
            for (Field field : c.getDeclaredFields()) {
                System.out.printf("Field: %s%n", field);
            }
        }
    }

     public class MyInnerClass {
    }
}
inner class: com.logicbig.example.MyClass$MyInnerClass
Constructor: public com.logicbig.example.MyClass$MyInnerClass(com.logicbig.example.MyClass)
Field: final com.logicbig.example.MyClass com.logicbig.example.MyClass$MyInnerClass.this$0

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) {
        }
    }
}
inner class: com.logicbig.example.MyClass2$MyInnerClass
Constructor: public com.logicbig.example.MyClass2$MyInnerClass(com.logicbig.example.MyClass2,java.lang.String,int)
Field: final com.logicbig.example.MyClass2 com.logicbig.example.MyClass2$MyInnerClass.this$0
instance: com.logicbig.example.MyClass2$MyInnerClass@5cad8086

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 {
    }
}
instance: com.logicbig.example.MyClass3$MyInnerClass@29453f44

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
                • MyClass.java

    See Also