Fun with initialization blocks

After Tomas posted the article Creating a Map in “Ruby-style” in Java, I wanted to tell you a little more about the { } block notation, which is used in that article to create a HashMap object. It looked like this:

new HashMap() {{
	put("name", "Tomas Salfischberger");
	put("phone", "123456789");
	put("room", "11b");
}};

The { } notation is called an “initialization block”. We can also see this notation in action in the following class:

public class Person {
	protected int age;

	// Initialization block
	{
		age = 30;
	}
	public Person() {
		age = 40;
	}
}

And you can feel it coming, the bonus-question here is: After creating a Person object, what is the value of the age field? You can try for yourself, or I can just tell you it will be 40. From that we can conclude that the init-block is executed before the constructor. If you check the documentation from Sun, you’ll find that init-blocks are indeed prepended to every constructor.

A new question arises: How could Tomas have used the put method in an init-block before the constructor of the HashMap has actually run? A more detailed look at the HashMap example reveals that what’s actually happening there, is the creation of a subclass of HashMap. This explains why the init-block runs after the constructor of HashMap: The init-block of the subclass is prepended to the constructor of the subclass, and the constructor of a subclass always runs after the constructor of its superclass.

A practical test confirms the following execution order of init-blocks and constructors:

- superclass init block
- superclass constructor
- your init block
- your constructor

You can also define multiple init-blocks, the runtime system guarantees they execute in the order that they appear in the source code. So all in all the init-blocks are a nice (and widely unknown) language feature which can be used to add general initialization to all constructors or in special cases to replace a no-argument constructor.

Comments

Leave a Reply