【发布时间】:2013-02-25 17:45:26
【问题描述】:
有一个代码是作为初级 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 关键字在超类上下文中的行为 - Calling base class overridden function from base class method
根据上面给出的规则,我假设有这样的顺序:
- 我们将创建一个类
B的新实例; - 我们去零件课
Main; - 用空值初始化
main.variable; - 然后我们转到
Main类的默认构造函数; - 构造函数在类
Main中调用方法b.printVariable(); (为什么不叫main.printvariable?我们这里没有this关键字。) - 字段
b.variable“变量在B类中初始化” - 现在我们回到课堂
B; - 我们应该用空值初始化字段
b.variable,对吗?; - 类
B的默认构造函数已执行
请,有人可以对这个继承初始化序列是如何工作的给出完整和完整的解释。以及为什么将String variable = null; 更改为String variable; 会导致另一个输出。
【问题讨论】:
-
printVariable() 是一个非常容易误导的方法名称 - 应该更像 setVariable()
-
你写java已经5年了,你还不知道调试器怎么用? (单步执行您的代码将向您确切显示正在发生的事情以及发生的顺序)。
-
@BrianRoach 当然我可以使用调试器,我还尝试了 javap -v -c B.class。但是每次当我看到 Java 开发人员的此类任务或面试问题时,我都会尝试预测输出并理解它,为什么它会这样工作以及如果我稍微修改代码会发生什么。单步执行并没有说明执行过程的规律和原因。
标签: java oop inheritance