初始化块的行为

时间:2013-06-07 12:59:06

标签: java constructor initialization

我有我无法理解的代码,它是如何产生输出的。以下是代码 -

代码:

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

问题:

我对此代码的具体问题是 -

  1. Hawk类初始化时,它会导致Raptor类进行实例化,因此静态代码块首先运行。但是,在打印pre之前,静态代码应该是非静态代码。不是吗?
  2. 那些非静态初始化块似乎实际上就像构造函数一样。那么,这些可以用作常规编程的构造函数吗?

4 个答案:

答案 0 :(得分:7)

  在打印之前,

静态代码后面应该是非静态代码。不是吗?

  1. 运行Hawk.main会触发所有三个类的初始化。这是静态初始化器运行的时候;
  2. pre已打印;
  3. new Hawk()触发所有三个类的实例初始值设定项的执行。
  4.   

    这些可以在常规编程中用作构造函数吗?

    它们最终与构造函数中的代码一起编译成<init>方法。所以是的,它们与构造函数代码类似。关键的区别在于,无论运行哪个构造函数,它们都会运行,并在构造函数体之前运行。

答案 1 :(得分:3)

在加载类时运行static块,因此它们甚至在方法main()运行之前就会运行。

初始化程序块在构造函数之前运行。构造函数和初始化程序块之间的区别在于约束器可以具有参数。

还要注意,初始化程序块和构造函数首先在基类中运行,然后在子类中运行。

答案 2 :(得分:0)

1 - 首先打印pre,因为你实际上只在运行new Hawk()时创建Hawk,直到那一刻,才会执行静态初始化器。

2 - 非静态初始化通常应用于从变量初始化值,但由于您无法将参数传递给它们,因此与构造函数相比,您不太可能实现相同的目标。在这些块中,您可以将属性初始化为常量值或空值。

答案 3 :(得分:0)

  1. 首先运行静态初始化程序(实际上按定义顺序)
  2. 您可以使用初始化程序块,但在声明或构造函数中初始化字段是一种常见的习惯用法。
  3. 详细Java tutorials document