实例初始化器和构造函数之间有什么区别?

只是想知道编译代码的原因是这样的:

class MyClass extends AnotherClass { { MySecondClass object = new MySecondClass(); object.doSomething(); } } 

这个代码和构造函数中的代码有什么区别? 此代码对象创建之前执行。

没有名称的大括号内的代码将成为类的构造函数的一部分,并在类构造函数中包含的逻辑之前执行。

快速举例:

 public class Foo { { System.out.println("Before Foo()"); } public Foo() { System.out.println("Inside Foo()"); } { System.out.println("Not After Foo()"); } } 

这称为实例初始化程序。 初始化程序中的代码在调用超类构造函数之后和其余构造函数代码之前插入。

任何构造函数的第一个操作是调用超类构造函数。 如果显式调用构造函数super(...) ,则使用指定的构造函数。 如果没有显式调用构造函数,则在超类中调用默认构造函数(不带参数)。 如果不存在这样的构造函数,则是编译时错误。

在此显式或隐式构造函数调用之后,将按照它们在源代码中出现的顺序调用实例初始值设定项(是的,您可以使用多个初始值设定项)。

为了说明,运行此程序打印

另一个构造函数
初始1
初始2
测试构造函数
 class Another { Another() { System.out.println("Another constructor"); } } class Test extends Another { public static void main(String[] args) { new Test(); } { System.out.println("Init 1"); } Test() { System.out.println("Test constructor"); } { System.out.println("Init 2"); } } 

最常见的应用程序是initalization中的“双括号初始化”习惯用法,其中定义了匿名内部类,并且一次创建和配置实例。 这是Swing编程中一个相当常见的例子:

 JButton popupButton = new JButton(new AbstractAction("Popup") { { putValue(Action.SHORT_DESCRIPTION, "Popup a dialog"); } @Override public void actionPerformed(ActionEvent evt) { popup(); } }); 

如果您有多个构造函数,并且需要在每个构造函数中执行一些无参数初始化,这可能很有用。 这可以作为初始化块的因素。

这是一个构造函数之前运行的实例初始化块 ,如果你问为什么要用它代替构造函数呢? 答案是否定的,你没有。

只是想知道编译代码的原因是这样的:

在使用构造函数重载时,通常使用它来分解公共代码。 因此,上面的“ the ”实际上是指执行公共实例初始化代码块之后在对象实例化时调用的重载构造函数之一。

顺便说一句,你有时可以通过调用另一个构造函数来实现相同的function,但调用必须在调用构造函数内的第一行,否则代码将无法编译。