26

使这种代码在 java 中有效的原因是什么?它是出于某种特定原因而存在,还是只是其他 Java 语言设计决策的副产品?你不能只使用consructor来达到同样的效果吗?

class Student
{
    {
        System.out.println("Called when Student class is instantiated.");
    }
}
4

4 回答 4

48

一点是它将执行调用的任何构造函数。如果您有多个构造函数并且它们不相互调用(无论出于何种原因,例如,每个都想调用一个直接对应的超类构造函数),这是确保为所有构造函数执行相同代码而不将其放入的一种方法一种可以在其他地方调用的方法。

当您编写匿名类时,它也可能很有用——您不能编写构造函数,但可以编写初始化程序块。例如,我已经看到它用于 JMock 测试。

于 2011-03-04T16:24:10.217 回答
20

它被称为初始化块

Java 编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。

于 2011-03-04T16:24:37.293 回答
5

它称为init 块在这样的块中,您可以对所有构造执行相同的逻辑,也可以将相同字段的声明初始化分开。

upd,当然还有双括号初始化,比如

List<Integer> answers = new ArrayList<Integer>(){{add(42);}}
于 2011-03-04T16:25:27.210 回答
5

这是一个初始化块。正如 Matt Ball 所提到的,它们被复制到每个构造函数中。

您可能有兴趣了解静态初始化块(也在 Matt 的链接中):

public class Foo {
    static {
        System.out.println("class Foo just got initialized!");
    }

    {
        System.out.println("an instance of Foo just got initialized!");
    }
}
于 2011-03-04T16:48:44.230 回答