3 回答
TA贡献1895条经验 获得超7个赞
因为所有静态字段(包括表示枚举值的静态字段)都是按文本顺序初始化的,而枚举值始终位于其他字段之前,所以在初始化静态字段之前会调用构造函数。请注意,在您的类示例中,您没有显示ABBREV_MAP的初始化位置-如果在 SUNDAY 之后,则在初始化类时会出现异常。
是的,这有点痛苦,可能设计得更好。
但是,根据我的经验,通常的答案是static {}
在所有静态初始化程序的末尾添加一个块,然后在其中进行所有静态初始化,EnumSet.allOf
以获取所有值。
TA贡献1802条经验 获得超6个赞
引用JLS,“枚举主体声明”部分:
没有此规则,由于枚举类型固有的初始化循环性,显然合理的代码将在运行时失败。(在具有“自类型”静态字段的任何类中都存在圆度。)这是将失败的那种代码的示例:
enum Color {
RED, GREEN, BLUE;
static final Map<String,Color> colorMap = new HashMap<String,Color>();
Color() {
colorMap.put(toString(), this);
}
}
此枚举类型的静态初始化将引发NullPointerException,因为在运行枚举常量的构造函数时,静态变量colorMap未初始化。上面的限制确保了此类代码不会编译。
请注意,可以轻松地将示例重构为正常工作:
enum Color {
RED, GREEN, BLUE;
static final Map<String,Color> colorMap = new HashMap<String,Color>();
static {
for (Color c : Color.values())
colorMap.put(c.toString(), c);
}
}
重构版本显然是正确的,因为静态初始化是自上而下进行的。
TA贡献2036条经验 获得超8个赞
也许这就是你想要的
public enum Day {
Sunday("Sun"),
Monday("Mon"),
Tuesday("Tue"),
Wednesday("Wed"),
Thursday("Thu"),
Friday("Fri"),
Saturday("Sat");
private static final Map<String, Day> ELEMENTS;
static {
Map<String, Day> elements = new HashMap<String, Day>();
for (Day value : values()) {
elements.put(value.element(), value);
}
ELEMENTS = Collections.unmodifiableMap(elements);
}
private final String abbr;
Day(String abbr) {
this.abbr = abbr;
}
public String element() {
return this.abbr;
}
public static Day elementOf(String abbr) {
return ELEMENTS.get(abbr);
}
}
添加回答
举报