Nescio Nescio - 5 months ago 17
Java Question

Initializing an instance variable in both parent and child

I have the following Java code

public class Base {
private static boolean goo = true;

protected static boolean foo() {
goo = !goo;
return goo;

public String bar = "Base:" + foo();

public static void main(String[] args) {
Base base = new Sub();

public class Sub extends Base {
public String bar = "Sub:" + foo();

And I'm asked what it would print. After testing this the answer seems to be
, but I'm really unable to understand why is it not

Running through the debugger with a Breakpoint on the final print I have the following object:
Debugger base

which shows base having two variables with the same name! one having the printed Base:false and the other the expected (by me) Sub:true. Indeed foo() is called twice but each time instantiating a different variable? Shouldn't the variable with the same name created in the subclass (and initialized after the first one is created) override the one in the parent class? How does Java choose which one to print?


...which shows base having two variables with the same name!

Yup! base is a reference to a Sub instance, and that Sub instance has two bar fields. Let's call them Base$bar and Sub$bar:

base--->|      Sub instance      |
        | Base$bar: "Base:false" |
        | Sub$bar:  "Sub:true"   |

Java allows for the same name being used at different levels in an instance's type hierarchy. (It has to: Frequently these are private fields, and so a subclass may not even know that the superclass has one with the same name.)

Those two different fields in the instance have different values: Base$bar has the value Base:false because it's initialized based on the first-ever call to foo, which flips goo (which starts as true) and using the flipped result. Sub$bar has the value Sub:true because it's initialized from a second call to foo, so goo is flipped again and the updated value is used. There is only one instance created, but foo is called twice.

Which one you see when you access bar depends on the type of the reference you have to the instance. Because base is declared of type Base, when you do you access the Base$bar field in the Sub instance. If you had a Sub reference to the instance, you'd use Sub$bar instead:

System.out.println(;        // "Base:false"
System.out.println(((Sub)base).bar); // "Sub:true"

Live Example