I stumbled upon this piece of code.
I tried to guess what will be the result of running it before actually doing so.
I was really confused when I saw them & in need
There are a few facts you ought to know before I start explaining every single step in your code's execution:
super()
is placed implicitly in every constructor even if you don't put it there yourself (it is not called if you call super(int x, int y)
for instance).Now let's break down your code step-by-step:
B
by calling its default constructor B()
.super()
is added implicitly to any constructor, so A()
is immediately called.A()
you call foo()
, which is overridden in class B
and that is why foo()
is called from B
.B
's foo()
you get the output B.foo(): bar = null
since Java didn't get to initialize B
's fields yet (its constructor hasn't been executed yet!) and the fields of object type are initialized to null
by default.A()
we go back to the constructor of B()
.foo()
again, which is again B
's foo()
. But different from last time, B
have its fields initialized (after the call to super()
) properly so you get the expected B.foo(): bar = B.bar
.main
.a.bar
, and since as I said field references are resolved based on reference type, you get the field bar
of A
.a.foo()
which again triggers B
's foo()
which prints b.bar
once again.And we are done! :)
Further references and worthwhile reading materials:
Static and dynamic binding explained
Order of constructor calls