Dvir Naim
Dvir Naim

Reputation: 335

When does the constructor initiallize?

I wrote down this mini-program:

A class:

public class A
{

    public A()
    {
        System.out.println(getS());
    }

    public String getS() { return s;}


}

B class:

public class B extends A
{
    private String s = "hello2";

    public String getS() { return s;}

}

main:

public static void main(String[] args)
{
    B b = new B();
}

and it printed:

null

Why is that?
I know that the String that printed is B's string, but why it didn't initialized before?

According to this answer - the variable initialized before the constructor..

EDIT - I edited the code so the unrelated code won't confuse

Upvotes: 1

Views: 137

Answers (3)

AxelH
AxelH

Reputation: 14572

What is happening:

You create a B instance, this will call the super() so the constructor of A.

Here it will do the print using the getter getS(). This will use the getter of B since this is the type of this but in this getter, the String is not yet instanciate since it is still doing the super class construction, so it return null.

Note that the String s in A is hidden by the one in B

The order during an instance is :

  • the static (from the super then the class)
  • the super class declaration (statement then constructor)
  • the block statement
  • the constructor

As Seen with :

public class A{
    static{System.out.println("sA");}
    {System.out.println("A1");}

    public Main() {
        System.out.println("new A");
    }

    {System.out.println("A2");}


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

class B extends Main {
    static{System.out.println("sB");}
    { System.out.println("B1"); }

    public B() {
        System.out.println("new B");
    }

    { System.out.println("B2"); }
}

Output :

sA
sB
A1
A2
new A
B1
B2
new B

Upvotes: 3

Aleksandr Lovkov
Aleksandr Lovkov

Reputation: 65

it prints null because you have polymorphism in java. You Overrided method getS(). So when you call it from A, you try to call getS() from class B. But you didn't create instance of class B yet, because you need to finish class A first. So String in class B haven't been initialized yet, because of it you get null.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726629

Here is what's going on: when you construct B, the first thing its constructor needs to do is constructing A. This is done before B's own field s is initialized.

A constructs its own s, and then calls getS. However, it does not get its own getS, because B provides an override for it. Recall that B.s has not been initialized yet. That is why you see null printed.

Follow-up reading: What's wrong with overridable method calls in constructors?

Upvotes: 5

Related Questions