我有我无法理解的代码,它是如何产生输出的。以下是代码 -
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 ");
}
}
r1 r4 pre b1 b2 r3 r2 hawk
我对此代码的具体问题是 -
Hawk
类初始化时,它会导致Raptor
类进行实例化,因此静态代码块首先运行。但是,在打印pre
之前,静态代码应该是非静态代码。不是吗?答案 0 :(得分:7)
在打印之前,静态代码后面应该是非静态代码。不是吗?
Hawk.main
会触发所有三个类的初始化。这是静态初始化器运行的时候; pre
已打印; new Hawk()
触发所有三个类的实例初始值设定项的执行。这些可以在常规编程中用作构造函数吗?
它们最终与构造函数中的代码一起编译成<init>
方法。所以是的,它们与构造函数代码类似。关键的区别在于,无论运行哪个构造函数,它们都会运行,并在构造函数体之前运行。
答案 1 :(得分:3)
在加载类时运行static
块,因此它们甚至在方法main()
运行之前就会运行。
初始化程序块在构造函数之前运行。构造函数和初始化程序块之间的区别在于约束器可以具有参数。
还要注意,初始化程序块和构造函数首先在基类中运行,然后在子类中运行。
答案 2 :(得分:0)
1 - 首先打印pre,因为你实际上只在运行new Hawk()时创建Hawk,直到那一刻,才会执行静态初始化器。
2 - 非静态初始化通常应用于从变量初始化值,但由于您无法将参数传递给它们,因此与构造函数相比,您不太可能实现相同的目标。在这些块中,您可以将属性初始化为常量值或空值。
答案 3 :(得分:0)