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

3
我有以下代码: 类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();
}

有人能解释一下为什么这个字符串会为空吗?


因为构造函数方法在amINull赋值之前被运行。 - ControlAltDel
1
这就是为什么你不应该在构造函数中调用可重写方法的原因。 - bradimus
2个回答

1

这里有一个关于初始化顺序的详细解释:

Java初始化和实例化顺序

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

  • 执行A类变量初始化器
  • 执行A类构造函数体
  • 返回到B类构造函数
  • 执行B类变量初始化器
  • 执行B类构造函数体

0
这是因为您首先检查字符串是否为空,然后再分配其值。当您扩展某个类时,该类的代码将首先执行!
您的编译器会按照以下方式进行操作: new B() -> isStringNull() -> private String amINull = "Of course not"; 请检查此修改后的代码并查看执行步骤会发生什么。
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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接