If you have a constructor which calls this() when is super() called? In the first constructor called? Or in the last constructor without the keyword this()?
Main calls: new B()
public class A {
public A(){
System.out.print("A ");
}
}
public class B extends A {
public B(){
// is super called here? Option 1
this(1);
System.out.print("B0 ");
}
public B(int i){
// or is super called here? Option 2
System.out.print("B1 ");
}
}
In this example the Output is: "A B1 B0". But it isn't clear to me, if the super() constructor is called at Option 1 or Option 2 (because the Output would be the same, in this case).
CodePudding user response:
When instantiating a new object, using new B()
, it automatically calls the no-arguments constructor. In your case, public B()
.
In the no-arguments constructor:
Because your constructor specified either a call to another constructor (using this()
) or a manually specified call to the superclass constructor (using super()
), there is no other call to another constructor. If your constructor was to only have the printing line (System.out.print("B0);
), super()
would have been automatically called. Now, you're calling this(1)
, so your first constructor won't output anything yet, but will go to your second constructor, having an int
argument.
In the second constructor (with int argument):
As I specified already, if your constructor doesn't have an explicit call to this()
or super()
, it automatically calls super()
(without any arguments unless manually specified). Because super()
must always be the first call in a constructor, it is executed before your print
, meaning that A()
is called. The first thing to be printed would be A
. Moving on, there will be B1
printed.
Back in your first constructor (no args):
this(1)
has already been called, so it moves to the next statement, the one that prints something. So B0
will be printed.
Now, as a recap, for a proper answer: super()
is automatically called only in public B(int i)
, because you already specified a call to this()
in your first constructor, and super()
is only called automatically when you don't specify this()
or an explicit call to super()
.
CodePudding user response:
You can deduce the answer by following this simple rule:
Only one super constructor will be called, and it will only be called once.
So, the super constructor could not possibly be invoked from B()
because it would be invoked again from B(int)
.
Specifically, in the Java Language Specification (JLS) section 8.8.7. "Constructor Body" we read:
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
In other words, if the constructor body does begin with an explicit constructor invocation, then there will be no implicit superclass constructor invocation.
(When the JLS speaks of a constructor body beginning with "an explicit constructor invocation" it means an invocation of another constructor of the same class.)