Why the following result is the output? Are class fields don't get initalized before the constructor?

Viewed 106

I want to understand why the result of the following code:

public class Base {
    private int member1 = 1;
    private int member2 = 2;

    public Base() {
        System.out.println("base ctor");
        print();
    }

    public void print() {
        System.out.println(member1 + "" + member2);
    }
}

class Derived extends Base {
    private int member3 = 3;
    private int member4 = 4;

    public Derived() {
        System.out.println("derived ctor");
        print();
    }

    public void print() {
        System.out.println(member3 + "" + member4);
    }
}

class Test{
    public static void main(String[] args) {
        Derived d = new Derived();
    }
}

is:

base ctor
00
derived ctor
34
  • the derived class's constructor implicitly calls its super

  • constructor. super's (base class) constructor prints "base ctor"

super's constructor calls print() - which prints member 1 , member 2 I thought that member1 and member2 already initialized because as I thought that I know, when we create an object the order of the things is static fields & blocks go first (if its the first load of the class) then instance things (like fields & members) go by order, which means what comes before in the order of the code.

Here - the fields come before the constructor, which means it should run and already initialize member1 and member2 before it reach print.

Why does it print 0 0?

Does it even go to the print of Base or it goes to the print of Derived? because it gets called from the constructor of Base so I don't get it.

Thanks.

1 Answers

You're calling the print method in Derived twice - once during the Base constructor, and once during the Derived constructor. That's because Derived.print() overrides Base.print().

So this expectation:

super's constructor calls print() - which prints member 1 , member 2

... is incorrect. It's calling the print() implementation in Derived, which prints member3 and member4. Those haven't been initialized yet.

The order of execution is:

  • Base class field initializers
  • Base class constructor body
  • Derived class field initializers
  • Derived class constructor body

If you just change your two print methods to print1 and print2 (and change the calling code appropriately) then it prints:

base ctor
12
derived ctor
34

... as you expected.

Related