chaitu
chaitu

Reputation: 1206

Is there a constructor associated with nested classes

I want to know if there are any constructors involved with inner classes. for example consider the code snippet given below

class MyOuter
{
   private int x= 10;

   class MyInner
   {
      void dostuff(){
         System.out.println("The value of x is "+x);
      }
   }
}

In another java file i create instances for both MyOuter and MyInner classes as shown below

Class Program
{
   public static void main(String [] args)
   {
      MyOuter mo = new MyOuter();
      MyOuter.MyInner mi = mo.new MyInner();
      mi.dostuff();
   }
}

The above code snippet compiles fine and gives output of "The value of x is 10".

What i want to know here is whether a constructor is invoked when new() is used with MyInner class and MyOuter class. If yes, then is there any constructor chaining from inner class to outer class (like subclass calls constructor of super class and so on).

Upvotes: 10

Views: 42642

Answers (5)

dash1e
dash1e

Reputation: 7807

You can observe the constructor chain for the inner class when you extend an inner class.

Take this example:

public class MainClass {

    public MainClass(String value) {
        System.out.println("mainValue: " + value);
    }

    public class NestedClass {

        public NestedClass(String nestedValue) {
            System.out.println("nestedValue: " + nestedValue);
        }
    }

}

and then extend the NestedClass like this

public class NestedClassExtension extends NestedClass {

    public NestedClassExtension(MainClass mainClass, String nestedValue) {
        mainClass.super(nestedValue);
    }
}

so you can see that you are able to call the super constructor of your nested class passing to that constructor the MainClass, and calling .super on mainClass object instance.

Now you can create NestedClassExtension instances in this way:

NestedClassExtension extension = new NestedClassExtension(new MainClass("main"), "nested");

So the main class has to exist, and its constructor it is called first. Then the constructors of the nested classes.

Instead if you want create a NestedClass instance outside of the MainClass you have to write:

MainClass mc = new MainClass("main");
mc.new NestedClass("nested");

Another time, the MainClass has to be created first, then the nested classes.

Upvotes: 14

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78579

If you compile your suggested code and then run the Java decompiler on it

javap MyOuter$MyInner

You would see how the compiler actually declare the constructor for your inner class:

public class MyOuter$MyInner extends java.lang.Object{
    final MyOuter this$0;
    public MyOuter$MyInner(MyOuter);
    void dostuff();
}

Here you can see that the compiler implements your inner class by declaring a final field member holding a reference to the enclosing class. The field is declared as final, and as such it is required to be provided a value to instantiate your Inner class.

When you do MyOuter.MyInner mi = mo.new MyInner() the compiler ensures the enclosing instance is passed as parameter.

This is done automatically by the compiler, and as such, you cannot chain the creation of your inner class with the creation of the outer class simply because the outer instance must already exist by the time you create the inner one.

You can, though, do constructor chaining between other declared constructors of your inner class.

For instance, if a code like this:

public class MyOuter
{
   private int x= 10;

   public class MyInner
   {
        private int y = 0;

        public MyInner(){
            this(10);
        }

        public MyInner(int value){
            this.y = value;
        }

        void doStuff(){
            System.out.println("The value of x is "+x);
        }
   }
}

Here I am chaining constructors withing the inner class.

Again, the decompiler ensures to interpret all this to make sure the outer instance is passed as a parameter to the inner one:

public class MyOuter$MyInner extends java.lang.Object{
    final MyOuter this$0;
    public MyOuter$MyInner(MyOuter);
    public MyOuter$MyInner(MyOuter, int);
    void doStuff();
}

Upvotes: 1

stacker
stacker

Reputation: 68962

If you don't specify a constructor a default constructor is created which takes no parameters. If you declare any other constructor say MyInner(int i) the creation of the default construtor is ommited and you would have to declare it yourself (if needed). Every Object (without any exceptions) is created by invoking a constructor.

Upvotes: 2

d1e
d1e

Reputation: 6442

They both are instantiated using default no-arg constructor. There is no chaining like in the inheritance's super(). It is just that you cannot instantiate an inner class without instantiation outer class first.

Read the difference between static and non-static inner class.

Upvotes: 2

Phani
Phani

Reputation: 5427

Inner constructor is only called when you have

MyOuter.MyInner mi = mo.new MyInner(); 

otherwise it will not even invoke inner class constructor as it is not instantiated, like static blocks are executed, but instance blocks and constructors are not invoked until you create an object.

Upvotes: 4

Related Questions