(代碼裏面的註釋和成員我就省略了)
如下問題雖然我是在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;