有一个代码作为初级Java开发人员的任务给出。我在五年的使用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
第二个输出对我来说更加清晰。 所以,据我所知inizialisation的在Java中这样的顺序:
- 我们去的类层次结构的根(用于Java它总是对象类),当我们来到这根父类:
- 所有静态数据字段初始化;
- 执行所有静态字段初始值设定项和静态初始化块;
- 所有非静态数据字段被初始化;
- 执行所有非静态字段初始化程序和非静态初始化块;
- 默认的构造函数被执行;
- 然后,我们不断为底层子类的程序。
也有帖子里面描述了一个超类的背景下this
关键字的行为 - Calling base class overridden function from base class method
基于上面给出的规则,我认为有顺序是这样的:
- 我们将创建
B
类的新实例; - 我们到部分类
Main
; - 用null初始化
main.variable
; - 然后我们转移到
Main
类的默认构造函数; - 构造在
Main
类调用方法b.printVariable()
; (为什么不调用它main.printvariable
我们没有在这里this
键字?) - 领域
b.variable
“变量是在B级初始化” - 现在我们再回到类
B
; - 我们应该初始化场
b.variable
与空值,是吗?; B
类的默认构造函数执行
请,能有人给的这种继承inizialisation序列是如何工作的一个完整的,全面的解释。以及为什么更改String variable = null;
到String variable;
导致另一个输出。
printVariable(会发生什么)是一个非常误导的方法名字 - 应该更像setVariable( ) – Jimmt 2013-02-25 17:50:45
你已经写了5年的Java,你不知道如何使用调试器? (单步执行代码会告诉你到底发生了什么以及按什么顺序)。 – 2013-02-25 18:04:55
@BrianRoach当然,我可以使用debuger,我也试过javap -v -c B.class。但是每次当我看到java开发人员或面试问题的这些任务时,我都会尝试预测输出并理解它,为什么它会像这样工作,以及如果稍微修改代码会发生什么情况。逐步进行并没有解释执行过程的规则和原因。 – INlHELL 2013-02-27 09:58:32