类变量未在子类Java中实例化

类变量未在子类Java中实例化,java,constructor,abstract-class,Java,Constructor,Abstract Class,我有以下代码:类A的构造函数调用由类B实现的抽象方法,该方法从类B返回一个变量。当A调用抽象方法时,该变量将为null,即使我在声明中实例化了它。有什么方法可以这样实例化它吗 public abstract class A { public A() { isStringNull(); } protected abstract String getMyString(); private void isStringNull () { if (getMyString() == nu

我有以下代码:类A的构造函数调用由类B实现的抽象方法,该方法从类B返回一个变量。当A调用抽象方法时,该变量将为null,即使我在声明中实例化了它。有什么方法可以这样实例化它吗

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

有人能解释一下为什么字符串是空的吗?

发生这种情况是因为您首先检查的是字符串是否为空,然后分配它的值。当您扩展某个类时,将首先执行该类代码

您的编译器是这样做的:
new B()
->
isStringNull()
->
private String amINull=“当然不是”

检查这段修改过的代码,看看会发生什么,看看执行步骤

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

此处详细说明了初始化顺序:

基本上,如果您调用一个超类构造函数(通过继承显式或隐式地调用,并且拥有一个无参数构造函数),那么它的所有初始化都会在返回子类之前完成。因此,在这种情况下,顺序是:

  • 执行A类变量初始值设定项
  • 执行A类构造函数主体
  • 返回到B类构造函数
  • 执行B类变量初始值设定项
  • 执行B类构造函数体

因为构造函数方法是在进行amINull赋值之前运行的,所以不应该从构造函数内部调用可重写的方法。