3

I have the following code: The constructor of class A calls an abstract method implemented by class B which returns a variable from class B. This variable will be null by the time A calls the abstract method even if I instantiated it in the declaration. Is there any way I can instantiate it this way?

public abstract class A {
public A() {
    isStringNull();
}

protected abstract String getMyString();

private void isStringNull () {
    if (getMyString() == null) {
        System.out.println("String is null :(");
    } else {
        System.out.println(getMyString());
    }
}
}

public class B extends A {
private String amINull = "Of course not";

@Override
protected String getMyString() {
    return amINull;
}
}

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

Can somebody please explain why the string will be null?

Apetroaei Andrei
  • 426
  • 4
  • 12

2 Answers2

1

There is a detailed explanation of the order of initialization here:

Java order of Initialization and Instantiation

Basically, if you call a superclass constructor (explicitly or implicitly by inheritance and having an argumentless constructor), all of its initialization is done before it comes back to the subclass. So, in this case, the order is:

  • perform class A variable initializers
  • perform class A constructor body
  • return to class B constructor
  • perform class B variable initializers
  • perform class B constructor body
Community
  • 1
  • 1
Piotr Wilkin
  • 3,446
  • 10
  • 18
0

This is happening because you are first checking is string null and then you are assigning its value. When you extend some class, that class code will be executed at first!

Your compiler is doing it this way: new B() -> isStringNull() -> private String amINull = "Of course not";

Check this modified code and see what will happen and look at execution steps

public abstract class A {
public A() {
    System.out.println("Class A() called");
    isStringNull();
}

protected abstract String getMyString();

private void isStringNull () {
    if (getMyString() == null) {
        System.out.println("String is null :(");
    } else {
        System.out.println(getMyString());
    }
}
}

public class B extends A {
System.out.println("Class B() called");
private String amINull = "Of course not";

@Override
protected String getMyString() {
    return amINull;
}
}

public static void main(String[] args) {
new B();
}
Aleksandar Đokić
  • 2,118
  • 17
  • 35