Reputation: 4084
I was going through this topics:
And I don't understand if we have a constructors, where we can put some logic, such as dealing with exceptional situations, why we need initialization blocks, which code we can also move to constructor ?
If the answer is that in some cases we need to initialize some resources before constructor runs would you help me with some examples, so I could fully see the picture.
Upvotes: 1
Views: 369
Reputation: 85789
why we need initialization blocks
For instance initialization blocks, I can only think on two cases:
When creating an anonymous class:
Runnable runnable = new Runnable() {
int x;
//initialization block here
{
//IMO this is such odd design, it would be better to not
//create this as an anonymous class
x = outerClassInstance.someMethod();
}
@Override
public void run() {
//write the logic here...
}
};
When using double brace initialization (if the class is not marked final
):
List<String> stringList = new ArrayList<>() {
{
add("Hello");
add("world");
}
};
System.out.println(stringlist);
//prints [Hello, world]
For static initialization blocks, there are two cases:
When defining the data for a static
field. This is covered in @ChrisThompson's answer.
When initializing a constant (static final
) field from an external source, like the result of some computation.
class Foo {
public static final boolean DEBUG;
static {
DEBUG = getDebugMode();
}
private static boolean getDebugMode() {
//code to open a properties file, read the DEBUG property
//and return the value
}
}
Upvotes: 1
Reputation: 35598
One example of a time when you'd use (and I have used) static initialization blocks is to initialize a collection of elements. For example, if I have some set of parsers that are stored in a static map:
private static Map<String, Parser> parsers = new HashMap<String, Parser>();
I may use a static initialization block to populate the members of this map:
static {
parsers.put("node", new NodeParser());
parsers.put("tree", new TreeParser());
parsers.put("leaf", new LeafParser());
//etc.
}
I would do this because I want the map to be static rather than part of a particular object, or if I only want there to be one of these maps (maybe I only need one).
The difference between this and a constructor is the constructor is called at object instantiation whereas the static initialization block will be called when the class is loaded.
That is, if you call
MyClass.parsers.get("node");
The MyClass
constructor is never called so if you waited to initialize the parsers
map until the constructor, the above call would return null.
Upvotes: 4