奇怪,但我找不到这个问题的副本。 我有一个带有overrideMe()方法的超类和一个覆盖它的子类。 在调用子类构造函数之前,是否真正初始化了final字段? 正如我从输出中看到的那样。
这是输出: 超类建设 str值:someValue 子类constr str值: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字段declasre为非final,则构造函数中的子类调用将返回null,如我所料。
答案 0 :(得分:2)
是的字段在调用构造函数之前被初始化,并且在重载之前从上层类开始。
以下是一般性演示:http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ306_014.htm
答案 1 :(得分:1)
初始化程序的最后一个字段将被编译器替换为const字符串,这就是为什么即使在超级构造函数返回之前字段也被初始化了。
如果final字段是空白的,这意味着它在子类的构造函数中,那么超级构造函数当然会看到null。
如果该字段既不是final也不是static,并且提供了初始值设定项,那么它将在超级构造函数之后和子构造函数之前进行。