Why is my field not being initialized with the value I gave it

I have the following classes:

public abstract class AClass {

    public AClass() {
        aMethod();
    }

    abstract protected void aMethod();

}

public class SubClass extends AClass {

    private int x = 5;
    private static final int y = 6;

    @Override
    protected void aMethod() {
        System.out.println("x: " + x + " | y: " + y);
    }

}

public class Main {

    public static void main(String[] args) {
        new SubClass();
    }

}

      

Running Main prints the following: x: 0 | y: 6

Why is 0 printed for x?

+3


source to share


6 answers


The wrong behavior is caused by the wrong initialization sequence:

  • new SubClass()

    executes the constructor AClass

  • AClass

    constructor calls aMethod()

  • aMethod()

    shows x

    (so far 0

    ) and y

    which is 6

    due to static)
  • SubClass

    initializes its non-static fields, so x

    it becomes 5

    .


To avoid surprises, never call virtual methods (esp. Overriden) in constructors

+10


source


A static field is initialized as soon as the class is initialized (after loading). Now when you call new SubClass()

the following events occur.



  • The constructor SubClass

    is called as the first statement SubClass

    (implicitly)
  • The constructor is called SuperClass

    . -> you are checking the value x

    here
  • Execution of the constructor SuperClass

    ends, then the instance-level fields are SubClass

    initialized. So, x

    will be initialized here.
+4


source


Initialization order. aMethod()

called before the lineprivate int x = 5

Playing with code examples like this is a great way to find out the order of things. Try adding static and non-static initialization block.

+3


source


The result is that the superclass's constructor is called before the elements are initialized.

In your case, the following sequence runs:

  • Constructor call SubClass

  • immediate constructor call AClass

  • method call aMethod()

  • member initialization SubClass

This is also the reason why you should not call any overridden methods from the constructor, as the called method can access the state of an object that is not fully initialized.

+3


source


private static final int y = 6;

      

The y value is 6 when the constructor calls aMethod () because it is static and initialized when classes are loaded.

private int x = 5;

      

For now, this initialization is appended to the end of your constructor body. This means that when aMethod is executed, the x variable has a default value ie 0.

The default SubClass constructor would look like

SubClass() {
    super();
    //All instance initialization are performed here.
}

      

+1


source


Because when you instantiated Subclass

, it calls the constructor of its superclass AClass

, and at that point x

it is not set yet why it gets the default 0.

0


source







All Articles