从 OCA/OCP Java SE 7 Programmer I & II Study Guide获取的以下代码产生以下输出:
r1 r4 pre b1 b2 r3 r2 hawk
我的解决方案错误:pre r1 r4 b1 b2 r3 r2 hawk
。
这是我遵循的逻辑:
首先,我们首先打印pre
实例化<{1}}之前的hawk()
static
块中的内容将首先打印出来:r1 r4
Bird
我们打印块中的内容然后构造函数中的内容:b1, b2
Raptor
,然后打印r3, r2
hawk
Hawk
class Bird {
{System.out.print("b1 "); }
public Bird()
{
System.out.print("b2 ");
}
}
class Raptor extends Bird {
static { System.out.print("r1 "); }
public Raptor()
{
System.out.print("r2 ");
}
{ System.out.print("r3 "); }
static { System.out.print("r4 "); }
}
class Hawk extends Raptor {
public static void main(String[] args) {
System.out.print("pre ");
new Hawk();
System.out.println("hawk ");
}
}
静态初始化块在类加载时执行;实例初始化 块在构造函数中调用super()之后立即运行。什么时候 单个类型的多个init块出现在类中,它们运行在 订单,自上而下。
pre
之前。r1 r4 b1 b2 r3 r2 pre hawk
static
方法中的内容然后一直向下打印pre
。然后它再次向上移动以打印blocks
和constructors
中的内容。然后终于打印出了鹰。这对我来说有点困惑。对不起如果我屠杀了java语言。
答案 0 :(得分:3)
类加载的顺序是:
static initialization blocks
instance initialization blocks
constructor
调用main
的{{1}}方法时,必须加载其类层次结构。从基类开始,将按顺序调用静态初始化块:
Hawk
第一个r1 r4
被称为
println
该类从下往上初始化。在每个类中,实例初始化块在ctor之前调用。在pre
Bird
b1 b2
中的
Raptor
然后调用最后一个println
r3 r2
答案 1 :(得分:2)
b1 b2 r3 r2
不是静态的,所以虽然它们确实是构造实例的一部分,但它们只有在创建后才会被调用(new Hawk();
之后出现pre
)
一般来说,你是正确的,它一直在无用的树上,它是这样做的两次:
- 第一次静止部分
- 构造函数的第二次,通过创建新的Hack
触发,因此在pre