Reputation: 478
I have such class written by some other developer:
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);
}
}
I am surprised by this part:
{
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);
}
}
Could someone please explain is this code valid and what is the advantage of using {} outside any method body?
Upvotes: 3
Views: 216
Reputation: 9775
It's an instance initializer. It's invoked when the object is created, right after the super()
in the constructor.
Refer to an example below:
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();
}
}
Running the main prints these two lines:
init block
constructor
That is because the constructor actually looks something like this:
public Test() {
super();
{
System.out.println("init block");
}
System.out.println("constructor");
}
Upvotes: 3
Reputation: 3078
It is instance initialization block.Instance initialization block code runs right after the call to super()
in a constructor, in other words, after all super constructors have run. The order in which initialization blocks appear in a class matters. If a class has more than one they all run in the order they appear in the class file.
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().
For more info click here.
Upvotes: 2
Reputation: 86411
This is an instance initializer block. It's called as part of initialization of an instance of the class.
You can also preface such a block with "static" to have it called once, when the class is initialized. This is called a static initializer.
From the Java Language Specification:
8.6. Instance Initializers
An instance initializer declared in a class is executed when an instance of the class is created (§12.5, §15.9, §8.8.7.1). ...
- It is a compile-time error if an instance initializer cannot complete normally (§14.21).
- It is a compile-time error if a return statement (§14.17) appears anywhere within an instance initializer.
- Instance initializers are permitted to refer to the current object via the keyword this (§15.8.3), to use the keyword super (§15.11.2, §15.12), and to use any type variables in scope.
- Use of instance variables whose declarations appear textually after the use is sometimes restricted, even though these instance variables are in scope. See §8.3.2.3 for the precise rules governing forward reference to instance variables.
Exception checking for an instance initializer is specified in §11.2.3.
Upvotes: 6
Reputation: 1806
This is instance initializer block. The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
Upvotes: 0
Reputation: 9954
The brackets denote an instance initializer. This is run directly before any constructor is run.
Upvotes: 0