Java枚举在枚举类的静态方法中为null

时间:2020-08-04 17:21:16

标签: java enums

我有一个枚举类来存储我的消息,我想在其中使用静态方法将其放入哈希图。

但是NullPointerException刚刚发生。 我该如何解决?

Msg.java

public enum Msg {

    //Common
    Message1("this"),
    Message2("is"),
    Message3("not"),
    Message4("cool");

    private String message;
    private static HashMap<Msg, String> Msgmap;
    
    private static HashMap<Msg, String> getMsgmap(){
        return Msgmap;
    }
    
    Msg(String msg) {
        this.message = msg;
        if(getMsgmap() == null) {
            setupMsgMap();
        }
    }

    private static void setupMessageMap() {
        Msgmap = new HashMap<Msg, String>();
        for(Msg msg :values()){
            Msgmap.put(msg, msg.message);
        }
    }
    
}

如果我替换

for(Msg msg:values()){
            langmap.put(msg, msg.message);
        }

使用

System.out.println(Message1.message);

还将抛出NullPointerException

但是,如果我尝试在构造函数中打印枚举字符串。 它将起作用。

2 个答案:

答案 0 :(得分:1)

如果可以的话,我建议您使用最终的不可变字段。这样,您不必担心线程安全。

您应该了解的一些信息:

  1. 枚举构造函数的调用次数与枚举所拥有的常量的次数相同。
  2. 对于具有至少一个常量的枚举,不可能编写将在构造函数之前调用的静态块。
  3. 在这种情况下,您可以在静态块中初始化静态字段。

以下是我的版本,基于@ charlie-armstrong代码:

enum Message { //the class is named "Message"
    Message1("this"),
    Message2("is"),
    Message3("not"),
    Message4("cool"); //line ends in a semicolon

    private static final HashMap<Message, String> Msgmap = new HashMap<>(); //Msgmap is initialized here

    static {
        for (Message msg : values()) { //loop through all the enum constants
            Msgmap.put(msg, msg.message); //add them all to the HashMap
        }
    }

    private final String message;

    Message(String msg) {
        this.message = msg;
        //I don't set up Msgmap in the constructor, because it is still initializing itself here, so we can't possibly add it to a HashMap yet
    }

    public static Map<Message, String> getMsgmap() {
        return Msgmap;
    }
}

答案 1 :(得分:0)

好的,您的代码有很多问题。首先,我将为您提供代码的注释版本,显示所有错误,然后提供有效的版本。这是您的代码:

public enum Msg { //should be called "Message", since it is in Message.java

    //Common
    Message1("this"),
    Message2("is"),
    Message3("not"),
    Message4("cool"), //syntax error, the line should end in a semicolon (;)

    private String message;
    private static HashMap<Msg, String> Msgmap; //Msgmap is never initialized
    
    private static HashMap<Msg, String> getMsgmap(){
        return Msgmap;
    }
    
    Msg(String msg) { //again, should be named "Message", not "Msg"
        this.message = msg;
        if(getMsgmap() == null) { //this will always be true, because Msgmap is never initialized
            setupMsgMap(); //this will run 4 times (once for every enum value)
        }
    }

    private static void setupMessageMap() {
        langmap = new HashMap<Lang, String>(); //syntax error (you didn't declare or infer a type), and the Lang class has not been provided to us, I assume you meant to use the Msg class instead
        for(Lang lang:values()){ //NullPointerException occurs here.  We're still initializing the first enum constant, but you're asking the compiler to loop through ALL the enum constants.  They aren't initialized yet though; they don't actually exist yet.
            langmap.put(lang, lang.lang);
        }
    }
    
}

这是我更新的代码:

public enum Message { //the class is named "Message"
    Message1("this"),
    Message2("is"),
    Message3("not"),
    Message4("cool"); //line ends in a semicolon

    private String message;
    private static HashMap<Message, String> Msgmap = new HashMap<>(); //Msgmap is initialized here

    public static HashMap<Message, String> getMsgmap() {
        return Msgmap;
    }

    Message(String msg) {
        this.message = msg;
        //I don't set up Msgmap in the constructor, because it is still initializing itself here, so we can't possibly add it to a HashMap yet
    }

    public static void setupMsgMap() { //this will need to be called from outside AFTER initialization
        for (Message msg : values()) { //loop through all the enum constants
            Msgmap.put(msg, msg.message); //add them all to the HashMap
        }
    }
}