我有一个类可能需要一个基于enum
类内容的大型但不变的数据结构。
我有兴趣知道的是,在static
块中初始化它是否更好,或者我是否应该在实际访问数据的方法中初始化它(如果它从未实际使用过的话) )?
以下是一个例子:
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>();
}
现在,我有两个初始化otherNames
地图的选项,首先是使用静态块,如下所示:
static {
for (MyEnum entry : MyEnum.values())
otherNames.put(entry.otherName, entry);
}
public static MyEnum valueByOtherName (String otherName) {
return otherNamesStatic.get(otherName);
}
或者我可以在第一次实际请求查找时初始化地图,如下所示:
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);
}
特别是我有兴趣知道Java是否会优化static
块,以便它可以在未来的运行中预先生成地图(因为它基于enum
,所以如果它没有' t改变了,然后没有地图)或者每次加载时它都会运行静态代码,在这种情况下只在需要时才更有效吗?
答案 0 :(得分:3)
每次加载类时都会执行静态块(而不是每次实例化对象时)。因此,除非您的环境使用多个类加载器,否则静态初始化块只会运行一次。
说完了,我建议使用更清洁的静态块(恕我直言)。
另请查看this answer以供参考。
答案 1 :(得分:1)
只要我理解Java,ClassLoader就会在加载类时调用静态初始化块,并且只在那一刻。所以:
valueByOtherName
,如果使用MyEnum类,也确定至少调用一次,并且在jvm关闭之前永远不会再调用它(除非你有独立的ClassLoaders加载相同的类,至少应该 strange )。但是您在valueByOtherName
valueByOtherName
时才会调用该块,并且永远不会再次调用构造。但是在每次调用valueByOtherName
恕我直言,使用静态块要好得多。它更具可读性......