Java 子类中的最终字段初始化
奇怪,但我找不到这个问题的副本。 我有一个带overrideMe()方法的超类和一个重写它的子类。 在调用子类构造函数之前,是否真正初始化了最后一个字段? 正如我从输出中看到的,它是 以下是输出: 超类构造 str值:someValue 子类constr str值:someValue 你能给我解释一下吗? 我认为实例变量是在构造函数调用中初始化的,但不是在它之前 代码如下:Java 子类中的最终字段初始化,java,initialization,Java,Initialization,奇怪,但我找不到这个问题的副本。 我有一个带overrideMe()方法的超类和一个重写它的子类。 在调用子类构造函数之前,是否真正初始化了最后一个字段? 正如我从输出中看到的,它是 以下是输出: 超类构造 str值:someValue 子类constr str值:someValue 你能给我解释一下吗? 我认为实例变量是在构造函数调用中初始化的,但不是在它之前 代码如下: public class Test { public Test() { System.out.println(
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字段定义为非final,则构造函数中对它的子类调用会像我预期的那样返回null。在调用构造函数之前初始化Yes字段,这从重载类之前的上层类开始
这里有一个一般的演示:编译器将用const字符串替换带有初始值设定项的最后一个字段,这就是为什么在超级构造函数返回之前该字段似乎已经初始化 如果最后一个字段为空inited,这意味着它是在子类的构造函数中初始化的,那么超级构造函数当然会看到null
如果该字段既不是最终字段,也不是静态字段,并且提供了初始值设定项,则它将在超级构造函数之后、子构造函数之前初始化。有关详细说明,这是一个非常愚蠢的问题:)我唯一仍然无法理解的是为什么最终字段最初没有初始化为null。@iozee最终字段从未更改。它不能初始化为null,然后再更改值。好吧,如果我拆分最终str字段的声明和初始化(在Ext的构造函数中初始化它),我会在超类overrideMe()调用中看到null?这个答案实际上是错误的,Adrian Liu的答案是正确的(区别在于子类的字段在调用超级构造函数之前没有初始化)。每个构造函数都首先调用
super
(或this
,后者调用super
),因此总是先初始化超类。(除了java.lang.Object
,后者没有super)