Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java enum在我的enum类的静态方法中获取null_Java_Enums - Fatal编程技术网

Java enum在我的enum类的静态方法中获取null

Java enum在我的enum类的静态方法中获取null,java,enums,Java,Enums,我有一个enum类来存储我的消息,我想在其中使用一个静态方法将它们放到hashmap中 但NullPointerException刚刚发生。 我怎样才能修好它 Msg.java public enum Msg { //Common Message1("this"), Message2("is"), Message3("not"), Message4("cool");

我有一个enum类来存储我的消息,我想在其中使用一个静态方法将它们放到hashmap中

但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);
        }
    }
    
}

还将抛出NullPointerException

但如果我试图在构造函数中打印枚举字符串。
它会正常工作。

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

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 Msg{//应称为“Message”,因为它位于Message.java中
//普通的
信息1(“本”),
信息2(“is”),
信息3(“非”),
Message4(“cool”),//语法错误,该行应以分号(;)结尾
私有字符串消息;
私有静态HashMap Msgmap;//Msgmap从未初始化
私有静态HashMap getMsgmap(){
返回Msgmap;
}
Msg(String Msg){//同样,应命名为“Message”,而不是“Msg”
this.message=msg;
如果(getMsgmap()==null){//这将始终为真,因为Msgmap从未初始化过
setupMsgMap();//这将运行4次(每个枚举值一次)
}
}
私有静态void setupMessageMap(){
langmap=new HashMap();//语法错误(您没有声明或推断类型),并且没有向我们提供Lang类,我假设您打算使用Msg类
对于(Lang-Lang:values()){//NullPointerException发生在此处。我们仍在初始化第一个枚举常量,但您要求编译器循环遍历所有枚举常量。但它们尚未初始化;它们实际上还不存在。
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
        }
    }
}
public enum Message{//该类名为“Message”
信息1(“本”),
信息2(“is”),
信息3(“非”),
Message4(“cool”);//行以分号结尾
私有字符串消息;
private static HashMap Msgmap=new HashMap();//Msgmap在这里初始化
公共静态HashMap getMsgmap(){
返回Msgmap;
}
消息(字符串消息){
this.message=msg;
//我没有在构造函数中设置Msgmap,因为它还在这里初始化自己,所以我们还不能将它添加到HashMap中
}
public static void setupMsgMap(){//初始化后需要从外部调用此函数
for(Message msg:values()){//遍历所有枚举常量
Msgmap.put(msg,msg.message);//将它们全部添加到HashMap中
}
}
}

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

您应该知道的一些信息:

  • 调用枚举构造函数的次数与枚举拥有的常量数相同
  • 对于至少有一个常量的枚举,不可能写入在构造函数之前调用的静态块
  • 在这种情况下,您可以在静态块中初始化静态字段
  • 以下是我的版本,基于@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;
        }
    }
    
    enum Message{//该类名为“Message”
    信息1(“本”),
    信息2(“is”),
    信息3(“非”),
    Message4(“cool”);//行以分号结尾
    private static final HashMap Msgmap=new HashMap();//Msgmap在这里初始化
    静止的{
    for(Message msg:values()){//遍历所有枚举常量
    Msgmap.put(msg,msg.message);//将它们全部添加到HashMap中
    }
    }
    私有最终字符串消息;
    消息(字符串消息){
    this.message=msg;
    //我没有在构造函数中设置Msgmap,因为它还在这里初始化自己,所以我们还不能将它添加到HashMap中
    }
    公共静态映射getMsgmap(){
    返回Msgmap;
    }
    }
    
    Plase,提供枚举类的完整源代码。您的代码似乎不完整,我发现编译错误。什么是langmap?在“Message”类中有什么?您应该遵循Java命名约定变量名称和方法名称应该用camelCase编写;PascalCase中的类名;和大写的常量(包括枚举常量)。对不起,我忘了用Msg替换Lang。编辑您可以使用
    静态{}
    块初始化映射。您可以使用它初始化映射,但不能填充映射,因为静态块在初始化程序之前运行。我刚刚在声明行初始化了它,两者都可以。@Polygenme是对的。看看我的答案或者。@user12292000是的,你和Polygonome是对的。。。我脑子里的初始化器和静态块是错误的。非常感谢。
    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
            }
        }
    }
    
    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;
        }
    }