Reputation: 3280
I have a class that may need a large, but unchanging, data-structure based on the contents of an enum
class.
What I'm interested to know is whether it is better for me to initialise this in a static
block, or should I only initialise it within the method that actually accesses the data (in case it's never actually used)?
Here's an example:
public enum MyEnum {
FOO ("foo"),
BAR ("bar"),
FOOBAR ("foo_bar");
private final String otherName;
private MyEnum (String otherName) {
this.otherName = otherName;
}
private static final Map<String, MyEnum> otherNames = new HashMap<String, MyEnum>();
}
Now, I have two options for initialising the otherNames
map, first being to use a static block like so:
static {
for (MyEnum entry : MyEnum.values())
otherNames.put(entry.otherName, entry);
}
public static MyEnum valueByOtherName (String otherName) {
return otherNamesStatic.get(otherName);
}
Or alternatively I can initialise the map the first time a lookup is actually requested like-so:
public static MyEnum valueByOtherName(String otherName) {
if (otherNames.isEmpty()) { // Or test against null or whatever
for (MyEnum entry : MyEnum.values())
otherNames.put(entry.otherName, entry);
}
otherNames.get(otherName);
}
In particular I'm interested to know whether Java will optimise the static
block such that it can pre-generate the map on future runs (since it's based on the enum
so if it hasn't changed, then neither has the map) or will it run the static code every time the class loads, in which case only doing it when needed may be more efficient?
Upvotes: 1
Views: 62
Reputation: 148910
As long as I understand Java, the ClassLoader calls the static initialization block at the moment it loads the class and only at that moment. So :
valueByOtherName
and it will never be called again until the jvm is closed (unless you have independant ClassLoaders loading same class which should be at least strange). But you have no extra test in valueByOtherName
valueByOtherName
and by construction will never be called again. But you have an extra test in each call to valueByOtherName
IMHO it is far better to use a static block. And it is far more readable ...
Upvotes: 2
Reputation: 4114
Static blocks are executed every time the class is loaded (not every time an object is instantiated). So, unless your environment uses several class loaders, your static initialization block will run only once.
Having that said, I'd suggest to use the static block which is cleaner (IMHO).
Also check this answer for your reference.
Upvotes: 3