Java enum получить null в методе stati c моего класса enum - PullRequest
0 голосов
/ 04 августа 2020

У меня есть класс перечисления для хранения моего сообщения, и я хочу использовать в нем метод stati c, чтобы поместить их в хэш-карту.

Но только что произошло исключение NullPointerException. Как я могу это исправить?

Сообщение 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 ]

1 голос
/ 04 августа 2020

Если можете, я рекомендую вам использовать final неизменяемые поля. Таким образом, вам не нужно беспокоиться о безопасности потоков.

Некоторая информация, которую вы должны знать:

  1. Конструктор перечисления вызывается столько раз, сколько констант имеет перечисление.
  2. Для перечислений, которые имеют хотя бы одну константу, невозможно написать блок stati c, который будет вызываться перед конструктором.
  3. В этом случае вы можете инициализировать поля stati c в stati c блок.

Ниже моя версия, основанная на коде @ charl ie -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;
    }
}
0 голосов
/ 04 августа 2020

Хорошо, с вашим кодом много проблем. Сначала я дам вам прокомментированную версию вашего кода, показывающую все, что не так, а затем предоставлю версию, которая действительно работает. Вот ваш код:

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...