只是想知道编译代码这样做的原因:
class MyClass extends AnotherClass {
{
MySecondClass object = new MySecondClass();
object.doSomething();
}
}
这段代码和构造函数中的代码有什么区别?这段代码在对象创建之前执行。
只是想知道编译代码这样做的原因:
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()");
}
}
javap -c
命令可以告诉你。) - millimoose这被称为实例初始化程序。初始化程序中的代码在调用超类构造函数之后,在构造函数的其余代码之前插入。
任何构造函数的第一个操作都是调用超类构造函数。如果显式调用了构造函数,super(...)
将使用指定的构造函数。如果没有显式调用任何构造函数,则会在超类中调用默认构造函数(不带参数的构造函数)。如果不存在这样的构造函数,则是编译时错误。
在此显式或隐式构造函数调用之后,按照它们在源代码中出现的顺序调用实例初始化程序(是的,您可以有多个初始化程序)。
为了说明,运行此程序会打印:
Another constructor Init 1 Init 2 Test constructor
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"); }
}
最常见的应用是在初始化"双括号初始化"习惯用法中,其中定义了一个匿名内部类,同时创建并配置实例。以下是Swing编程中一个相当常见的示例:
JButton popupButton = new JButton(new AbstractAction("Popup") {
{
putValue(Action.SHORT_DESCRIPTION, "Popup a dialog");
}
@Override
public void actionPerformed(ActionEvent evt)
{
popup();
}
});
如果您有多个构造函数,并且需要在每个构造函数中执行一些无参数初始化,则可以使用此方法。这可以合并到一个初始化块中。
通常情况下,当使用构造函数重载时,您可以使用它来提取公共代码。因此,上面的"the"实际上是指在执行公共实例初始化代码块后,在对象实例化时调用的重载构造函数之一。只是想知道编译这样的代码的原因: