3

我有其他一些开发人员编写的此类:

public class ManifestFile implements Serializable {

private final static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private final static XPathFactory xPathFactory = XPathFactory.newInstance();
private final static DateFormat YYYYMMDD = new SimpleDateFormat("yyyyMMdd");
private final String uuid;
private final Set<File> attachments = new LinkedHashSet<File>();
private final transient ApplicationContext applicationContext = JavaService.INSTANCE.getApplicationContext();
private final transient File attachmentDirectory;
private final Date processAfter = new Date(System.currentTimeMillis() + 3 * 1000 * 60);

{
    try {
        documentBuilderFactory.setNamespaceAware(true);
        final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(new StreamSource(getClass().getResourceAsStream("/StrategicEmail5.xsd")));
        documentBuilderFactory.setSchema(schema);
        documentBuilderFactory.setValidating(true);
    } catch (Throwable t) {
        throw new RuntimeException(t);
    }
}

我对这部分感到惊讶:

{
try {
    documentBuilderFactory.setNamespaceAware(true);
    final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = sf.newSchema(new StreamSource(getClass().getResourceAsStream("/StrategicEmail5.xsd")));
    documentBuilderFactory.setSchema(schema);
    documentBuilderFactory.setValidating(true);
} catch (Throwable t) {
    throw new RuntimeException(t);
}
}

有人可以解释一下这段代码是否有效,在任何方法体之外使用 {} 有什么好处?

4

5 回答 5

6

这是一个实例初始化程序块。它被称为类实例初始化的一部分。

您还可以在此类块初始化时使用“静态”作为前言,以使其调用一次。这称为静态初始化程序。

来自Java 语言规范

8.6. 实例初始化器

在创建类的实例时执行在类中声明的实例初始化程序(第 12.5 节、第 15.9 节、第 8.8.7.1 节)。...

  • 如果实例初始化程序无法正常完成(第 14.21 节),则为编译时错误。
  • 如果 return 语句(第 14.17 节)出现在实例初始化程序中的任何位置,则是编译时错误。
  • 允许实例初始化器通过关键字 this(第 15.8.3 节)引用当前对象,使用关键字 super(第 15.11.2 节,第 15.12 节),以及使用范围内的任何类型变量。
  • 有时限制使用在使用后以文本形式出现声明的实例变量,即使这些实例变量在范围内。有关管理对实例变量的前向引用的精确规则,请参见第 8.3.2.3 节。

实例初始化程序的异常检查在 §11.2.3 中指定。

于 2013-06-17T12:55:03.983 回答
3

它是一个实例初始化器。它在创建对象时调用,就super()构造函数中的 之后。

请参考以下示例:

public class Test {
    //instance initializer
{
    System.out.println("init block");
}

    public Test() {
        super();
        System.out.println("constructor");
    }

        //invoke to test
    public static void main (String ... args) {
        new Test();
    }
}

运行 main 打印这两行:

init block
constructor

那是因为构造函数实际上看起来像这样:

public Test() {
    super();
    {
        System.out.println("init block");
    }
    System.out.println("constructor");
}
于 2013-06-17T12:55:43.010 回答
2

它是实例初始化块。实例初始化块代码super()在构造函数中调用之后立即运行,换句话说,在所有超级构造函数都运行之后。初始化块出现在类中的顺序很重要。如果一个类有多个,它们都按照它们在类文件中出现的顺序运行。

Some rules to remember:
 1.Initialization blocks execute in the order they appear.
 2.Static Initialization blocks run once when the class is first loaded.
 3.Instance Initialization blocks run every time a class instance is created.
 4.Instance Initialization blocks run after the constructor’s call to super().

欲了解更多信息,请单击此处

于 2013-06-17T13:01:48.843 回答
0

括号表示实例初始化器。这是在任何构造函数运行之前直接运行的。

于 2013-06-17T12:55:44.307 回答
0

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

于 2013-06-17T12:56:54.147 回答