A question on Java constructor and class member initialization
I’m trying to understand why the output of the following Java code is as like this:
class A { public A() { System.out.print("A()"); } public static void main(String[] args) { } } class B { public B() { System.out.print("B()"); } public static void main(String[] args) {} } class C extends A { B b = new B(); } public class E05SimpleInheritance { public static void main(String args[]) { new C(); } }
Output:
"A()B()"
I would imagine that when the main method of the E05SimpleInheritance public class is called the following things should happen
- Non-public class C is loaded and its fields are initialized(before calling the default constructor of class C)
- Since its member ‘b’ is an object of class B, class B is loaded in memory
- Since we construct an object of Class B its constructor is called which should print B()
- Default constructor of C is called which automatically calls the constructor of the superclass A which print A()
So the final output should be B()A() which is obviously wrong so I do not really understand how the code flows in this case. Can you perhaps show me why is A()B() printed instead of B()A()
Your mistake is in step 1:
Non-public class C is loaded and its fields are initialized(before calling the default constructor of class C)
This is not what’s happening. In reality, non-static fields are initialised at the beginning of the constructor, not before it. And the base class constructor is implicitly (or explicitly) invoked even before that.
In other words, javac
generates code for C
which is equivalent to the following:
class C extends A { B b; C() { super(); b = new B(); } }