【Java编程】用枚举类初始化内部类的坑
问题
年底写了一个程序,由于代码库经常有人将枚举类当中的各项数值进行分类,存储到相应的map当中。
然后快速用key判断或者拿到实例。
在重构的过程中,发现访问这个Map的时候,其实是空的。
System.out.println(MonitorEnum.MetaData.flinkMonitorMap.size()); // 输出 0
public enum MonitorEnum {
A("flink", "source_rps"),
B("flink", "checkpoint_failed");
public static final class MetaData {
public static final Map<String, MonitorEnum> flinkMonitorMap = new HashMap<>(); //数据在这
}
private final String type;
private final String name;
MonitorEnum(String type, String name) {
this.type = type;
this.name = name;
if ("flink".equals(type)) {
MetaData.flinkMonitorMap.put(name, this); //初始化在这
}
}
}
分析
看到这种问题,立马想到初始化的问题。于是询问Claude,Claude自己都没发现问题。。。于是把现象告诉GPT,GPT却很快理解了这个问题。
MonitorEnum.values();
System.out.println(MonitorEnum.MetaData.flinkMonitorMap.size()); // 输出 2
解决
应当在MetaData当中初始化这个Map
public static final class MetaData {
public static final Map<String, MonitorEnum> flinkMonitorMap = new HashMap<>();
static {
for (MonitorEnum e : MonitorEnum.values()) {
if ("flink".equals(e.type)) {
flinkMonitorMap.put(e.name, e);
}
}
}
}
总结
JVM在访问MetaData的时候,并不会直接初始化MonitorEnum,即便MetaData在MonitorEnum的“内部”。对于JVM来说不过是MonitorEnum$MetaData 另一个类型而已。
在明确的规则之下,程序设计应该是责任明确的。

浙公网安备 33010602011771号