“`java 在我的枚举类的静态方法中获取Java枚举为空 “`

huangapple go评论74阅读模式
英文:

Java enum get null in static method of my enum class

问题

I got a enum class to store my message and I want to use a static method in it to put them to a hashmap.

But NullPointerException just happened.
How can I fix it?

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) {
			setupMessageMap();
		}
	}

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

If I replace

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

with

System.out.println(Message1.message);

will also throw NullPointerException

But if I try to print my enum strings in constructor.
It will just work.

英文:

I got a enum class to store my message and I want to use a static method in it to put them to a hashmap.

But NullPointerException just happened.
How can I fix it?

Msg.java

public enum Msg {

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

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

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

If I replace

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

with

System.out.println(Message1.message);

will also throw NullPointerException

But if I try to print my enum strings in constructor.
It will just works.

答案1

得分: 1

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

一些你应该知道的信息:

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

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

enum Message { // 类名为 "Message"
    Message1("this"),
    Message2("is"),
    Message3("not"),
    Message4("cool"); // 行以分号结束

    private static final HashMap<Message, String> Msgmap = new HashMap<>(); // 在这里初始化Msgmap

    static {
        for (Message msg : values()) { // 循环遍历所有枚举常量
            Msgmap.put(msg, msg.message); // 将它们全部添加到HashMap中
        }
    }

    private final String message;

    Message(String msg) {
        this.message = msg;
        // 我不在构造函数中设置Msgmap,因为它仍然在这里初始化自己,所以我们不能立即将它添加到HashMap中
    }

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

If you can, i recommend you to use final immutable fields. This way you don't have to worry about thread safety.

Some information you should know:

  1. Enum constructor is called as many times as many constants the enum has.
  2. For enums which have at least one constant, it is impossible to write static block which will be called before constructor.
  3. In this case you can init static fields in static block.

Below is my version, based on @charlie-armstrong code:

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

    private static final HashMap&lt;Message, String&gt; Msgmap = new HashMap&lt;&gt;(); //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&#39;t set up Msgmap in the constructor, because it is still initializing itself here, so we can&#39;t possibly add it to a HashMap yet
    }

    public static Map&lt;Message, String&gt; getMsgmap() {
        return Msgmap;
    }
}

答案2

得分: 0

以下是您的代码的翻译:

public enum Msg { //应该叫做“Message”,因为它在Message.java中

    //Common
    Message1("this"), //消息1
    Message2("is"), //消息2
    Message3("not"), //消息3
    Message4("cool"), //语法错误,行应该以分号(;)结束

    private String message; //私有字符串变量
    private static HashMap<Msg, String> Msgmap; //Msgmap从未初始化

    private static HashMap<Msg, String> getMsgmap(){
        return Msgmap;
    }

    Msg(String msg) { //再次强调,应该命名为“Message”,而不是“Msg”
        this.message = msg;
        if(getMsgmap() == null) { //这将始终为true,因为Msgmap从未初始化
            setupMsgMap(); //这将运行4次(每个枚举值运行一次)
        }
    }

    private static void setupMessageMap() {
        langmap = new HashMap<Lang, String>(); //语法错误(您没有声明或推断类型),而且Lang类没有提供给我们,我假设您想使用Msg类而不是Lang类
        for(Lang lang:values()){ //在此处发生NullPointerException。我们仍在初始化第一个枚举常量,但您要求编译器循环遍历所有枚举常量。但它们还没有初始化,实际上它们还不存在。
            langmap.put(lang, lang.lang);
        }
    }
    
}

以下是更新后的代码:

public enum Message { //类名为“Message”
    Message1("this"), //消息1
    Message2("is"), //消息2
    Message3("not"), //消息3
    Message4("cool"); //行以分号结束

    private String message; //私有字符串变量
    private static HashMap<Message, String> Msgmap = new HashMap<>(); //在此处初始化Msgmap

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

    Message(String msg) {
        this.message = msg;
        //我不在构造函数中设置Msgmap,因为它仍在此处初始化,所以我们不可能将其添加到HashMap中
    }

    public static void setupMsgMap() { //这需要在初始化之后从外部调用
        for (Message msg : values()) { //循环遍历所有枚举常量
            Msgmap.put(msg, msg.message); //将它们全部添加到HashMap中
        }
    }
}
英文:

Okay, there are many issues with your code. I will first give you a commented version of your code, showing everything that's wrong, and then I will provide a version that does work. Here is your code:

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

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

    private String message;
    private static HashMap&lt;Msg, String&gt; Msgmap; //Msgmap is never initialized
    
    private static HashMap&lt;Msg, String&gt; getMsgmap(){
        return Msgmap;
    }
    
    Msg(String msg) { //again, should be named &quot;Message&quot;, not &quot;Msg&quot;
        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&lt;Lang, String&gt;(); //syntax error (you didn&#39;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&#39;re still initializing the first enum constant, but you&#39;re asking the compiler to loop through ALL the enum constants.  They aren&#39;t initialized yet though; they don&#39;t actually exist yet.
            langmap.put(lang, lang.lang);
        }
    }
    
}

Here's my updated code:

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

    private String message;
    private static HashMap&lt;Message, String&gt; Msgmap = new HashMap&lt;&gt;(); //Msgmap is initialized here

    public static HashMap&lt;Message, String&gt; getMsgmap() {
        return Msgmap;
    }

    Message(String msg) {
        this.message = msg;
        //I don&#39;t set up Msgmap in the constructor, because it is still initializing itself here, so we can&#39;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
        }
    }
}

huangapple
  • 本文由 发表于 2020年8月5日 01:21:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63252008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定