Reputation: 1206
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
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
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
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
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
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