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

时间:2016-08-17 15:00:30

标签: 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() == 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();
}

有人可以解释为什么字符串会为空吗?

2 个答案:

答案 0 :(得分:1)

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

Java order of Initialization and Instantiation

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

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

答案 1 :(得分:0)

这种情况正在发生,因为您首先检查的是字符串null,然后您正在分配其值。扩展某个类时,首先会执行该类代码!

您的编译器正是这样做的: 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();
}