有一段代码是给初级Java开发人员的任务。我已经使用Java五年了,但这段代码完全让我困惑:
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
输出结果将为:
Hello World!
variable value = null
但是如果我们将String variable = null;
更改为String variable;
,我们会得到:
Hello World!
variable value = variable is initialized in B Class
第二个输出对我来说更清晰。就我所知,Java的初始化顺序如下:
- 我们进入类层次结构的根(对于Java,它始终是Object类),当我们到达此根父类时:
- 所有静态数据字段都被初始化;
- 执行所有静态字段初始值设定项和静态初始化块;
- 初始化所有非静态数据字段;
- 执行所有非静态字段初始值设定项和非静态初始化块;
- 执行默认构造函数;
- 然后我们为底层子类重复该过程。
此外,还有一篇文章描述了this
关键字在超类上下文中的行为 - 从基类方法调用基类覆盖函数
根据上述规则,我假设序列如下:
- 我们将创建类
B
的一个新实例; - 我们转到类
Main
部分; - 用null初始化
main.variable
; - 然后我们移动到类
Main
的默认构造函数; - 构造函数在类
Main
中调用方法b.printVariable()
;(为什么不调用main.printvariable
?这里没有使用this
关键字。) - 字段
b.variable
"变量在B类中初始化" - 现在我们回到类
B
; - 我们应该使用null值初始化字段
b.variable
,是吗?; - 执行类
B
的默认构造函数
请问有人可以完整详细地解释一下这个继承初始化顺序是如何工作的吗?以及为什么将String variable = null;
更改为String variable;
会导致另一种输出。