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?

2
  • Because the constructor method is being run before the amINull assignment is made Commented Aug 17, 2016 at 15:02
  • 1
    This is why you should not call overridable methods from inside a constructor. Commented Aug 17, 2016 at 15:05

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

Comments

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();
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.