0

I'm pretty confused by the following code... Can somebody explain why overridden method getX() prints different result than getX_1(), and why it prints different result inside parent constructor, and outside the class ? (It's not a question about "polymorphic fields", cause no fields are accessed outside the class, it's about different behavior of methods that are invoked inside, or outside the constructor, and when actually instance fields are initialized).

public class TestInstanceVars {

public static void main(String[] args) {
    C c = new C();
    p("----- Third ----");
    c.getX(); // 3 ... initilized!
}
private static void p(Object x){
    System.out.println(x);
}


private static class A {
    int x = 1;
    A() {
        p("----- First ----");
        getX(); // 0 ... uninitialized ?
        getX_1(); // 1 ... initialized ?
    }
    public int getX(){
        p("Inside A::getX() ... x = " + x);
        return x;
    }
    public int getX_1(){
        p("Inside A::getX_1() ... x = " + x);
        return x;
    }
}
private static class B extends A {
    int x = 2;
    B() {
        p("----- Second ----");
        getX(); // 0 ... uninitialized
        getX_1(); // 1 ... initialized ?
    }
}
private static class C extends B {
    int x = 3;
    @Override
    public int getX(){
        p("Inside C::getX() ... x = " + x);
        return x;
    }
}

}
DominikStyp
  • 360
  • 6
  • 10
  • There are a number of issues here. The main is the _hiding_ of fields. Each of your classes has its own `x` and fields are not polymorphic. When you refer `x` in any of those classes, it always refers to the `x` declared in whatever you're using it. For example, your `C#getX` implementation will refer to `C#x`, but `A#getX` will refer to `A#x`. Once you understand that, the rest is simple. It's just regular order of initialization (superclasses first) and polymorphism (overriden methods get called). – Sotirios Delimanolis Apr 28 '16 at 14:37
  • @SotiriosDelimanolis Thanks for the answer, but one thing still doesn't seems to be clear for me: Why overridden method getX() from C invoked in A() constructor returns 0 (uninitialized it seems) where not overridden getX_1() returns 1. Is this mean that overridden getX() doesn't see initialized variable from C because initialization of the C class isn't completed in A() constructor ? – DominikStyp Apr 28 '16 at 22:02
  • 1
    Field initializer expressions are executed after any super constructors. Within the `A` constructor, the `C#x` field has yet to be initialized to `3`. It still has its default value of `0`. `A#getX_1()` is referring to `A#x` which has been initialized to `1`. – Sotirios Delimanolis Apr 28 '16 at 22:06

0 Answers0