Есть ли обходной путь для невозможности доступа к методам stati c в перечислении внутри его конструктора? - PullRequest
0 голосов
/ 04 августа 2020

У меня есть перечисление, в котором все элементы имеют уникальные идентификаторы. В моем конструкторе я генерирую исключение, если уже существует элемент с данным идентификатором, например:

public enum Number {

    ONE(1),
    TWO(2),
    THREE(3);

    private final int id;

    private Number(int id) {
        if (Number.isRegistered(id)) throw new IllegalArgumentException(id + " is already registered.");
        this.id = id;
    }

    public static Number getNumberFromID(int id) {
        for (Number n : Number.values()) {
            if (n.getID() == id) return n;
        }

        throw new IllegalArgumentException("There is no number with the ID " + id);
    }

    public static boolean isRegistered(int id) {
        try {getNumberFromID(id);}
        catch (IllegalArgumentException e) {return false;}
        return true;
    }

    public int getID() {
        return this.id;
    }

}

И в другом классе я пытаюсь сослаться на это:

public class Main {
    public static void main(String[] args) {
        Number one = Number.getNumberFromID(1);
    }
}

Который дает следующую ошибку:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at Main.main(Main.java:8)
Caused by: java.lang.NullPointerException
    at Number.values(Number.java:1)
    at Number.getNumberFromID(Number.java:15)
    at Number.isRegisteredNumber(Number.java:23)
    at Number.<init>(Number.java:10)
    at Number.<clinit>(Number.java:3)
    ... 1 more

Это не мой точный код, поэтому он кажется немного бессмысленным, но он показывает, что я пытаюсь сделать. Из того, что я обнаружил, кажется, что Java не позволяет вам получить доступ к методам stati c в таком перечислении, потому что он все еще создается. Кто-нибудь знает, как это сделать лучше? Любая помощь приветствуется.

1 Ответ

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

Добавьте инициализатор stati c в свой класс:

public enum Number {

    ONE(1),
    TWO(2),
    THREE(3);

    static {
      Set<Integer> seen = new HashSet<>();
      for (Number n : values()) {
        if (!seen.add(n.id)) {
          throw new IllegalArgumentException(...); 
        }
      }
    }

    private final int id;

    private Number(int id) { this.id = id }
}
...