(代码里面的注释和成员我就省略了)
如下问题虽然我是在enum里遇到的,实际上enum也是个Class,放在Class上照样会出问题。
事情的原由是项目里面有个enum,定义了两个属性code和description,相似以下结构: java
public enum LogType { LOGIN("login", "登录日志"), ADMIN("admin", "系统管理日志"); private String code = null; private String description = null; private LogType(String code, String description) { this.code = code; this.description = description; } }
可是我在数据库中存储的是code的值,就须要一个方法能够把code转换成对应的枚举,这时就想到建立一个成员,在构造函数里面注册一下,而后就有了如下的改动,却编译报错: 数据库
// 增长一个存放code和LogType值对应关系的Map private static Map<String, LogType> instances = new HashMap<>(); // 原计划在构造函数中向map添加这个对象自己,却不能经过编译 private LogType(String code, String description) { // 这行报错: Cannot refer to the static enum field LogType.instances within an initializer instances.put(code, this); this.code = code; this.description = description; }你不是不让我在构造函数里面直接使用enum的static成员吗,那好办,再改一下:
private static Map<String, LogType> instances = new HashMap<>(); private void registerCode(String code) { instances.put(code, this); } private LogType(String code, String description) { registerCode(code); this.code = code; this.description = description; }这下总能经过编译了吧,我又没在构造函数中直接使用static成员。结果一运行,instances.put(code, this)抛出NullPointerException!!!我不是已经new HashMap<>()了吗。下来查了下资料,获得这样一个说法:
public static final LogType LOGIN = new LogType("login", "登录日志"); public static final LogType ADMIN = new LogType("admin", "系统管理日志"); private static Map<String, LogType> instances = new HashMap<>();对LogType()函数的调用是早于new HashMap<>()这句的执行的。因此NullPointerException就不奇怪了
private static Map<String, LogType> instances = null; private static Map<String, LogType> getInstances() { // 若是instances是null,就给他一个hashMap if (instances == null) { instances = new HashMap<>(); } return instances; } // 调用getInstances()而不是直接使用instances,这样就保证instances不为null咯 private void registerCode(String code) { getInstances().put(code, this); }一运行,果真能够了,那继续写find方法
public static LogType find(String code) { return instances.get(code); }使用的时候,又在find里面抛出NullPointerException!!!刚刚构造函数的那里getInstances()明明已经赋值了,我registerCode都放了东西进去了,怎么可能仍是null,这不科学。
private static Map<String, LogType> instances;