2

奇怪,但我找不到这个问题的重复项。我有一个带有 overrideMe() 方法的超类和一个覆盖它的子类。在调用子类构造函数之前,final 字段真的被初始化了吗?正如我从输出中看到的那样,它是。

下面是输出: Superclass constr str value: someValue Subclass constr str value: someValue

你能给我解释一下吗?我认为实例变量是在构造函数调用中初始化的,但不是在它之前。

这是代码:

public class Test {
  public Test() {
    System.out.println("Superclass constr");
    overrideMe();
  }

  public void overrideMe() {
  }
}

class Ext extends Test {
  private final String str = "someValue";

  public Ext() {
    System.out.println("Subclass constr");
  }

  @Override
  public void overrideMe() {
    System.out.println("str value: " + str);
  }

  public static void main(String[] args) {
    Ext test = new Ext();
    test.overrideMe();
  }
}

编辑: 如果我将 str 字段声明为非最终字段,则它在构造函数中的子类调用将按我的预期返回 null。

4

2 回答 2

2

是的,字段在调用构造函数之前被初始化,这从重载之前的上层类开始。

这是一个一般介绍:http ://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ306_014.htm

于 2012-06-18T09:24:33.807 回答
1

带有初始化程序的最终字段将被编译器替换为 const 字符串,这就是为什么该字段似乎在超级构造函数返回之前就已初始化的原因。

如果 final 字段是空白初始化的,这意味着它是在子类的构造函数中初始化的,那么超级构造函数当然会看到一个空值。

如果该字段既不是 final 也不是 static,并且提供了一个初始化器,那么它将在超级构造函数之后和子构造函数之前进行初始化。

于 2017-01-24T07:47:44.277 回答