有没有绕过无法在枚举的构造函数内访问静态方法的方法?

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

Is there a workaround for not being able to access static methods in an enum inside its constructor?

问题

我有一个枚举类型,在其中的元素都具有唯一的ID。在我的构造函数中,如果已经存在具有给定ID的元素,我会抛出异常,就像这样:

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 + " 已经注册。");
        this.id = id;
    }

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

        throw new IllegalArgumentException("不存在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不允许你在这种情况下访问枚举中的静态方法,因为枚举仍在构建中。有人知道更好的方法吗?任何帮助将不胜感激。

英文:

I have an enum in which the elements all have unique IDs. In my constructor I throw an exception if there already exists an element with the given ID, like this:

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 + &quot; is already registered.&quot;);
        this.id = id;
    }

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

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

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

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

}

And in another class I try to reference this:

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

Which gives the following error:

Exception in thread &quot;main&quot; 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.&lt;init&gt;(Number.java:10)
	at Number.&lt;clinit&gt;(Number.java:3)
	... 1 more

This isn't my exact code, which is why it seems a bit pointless, but it shows what I'm trying to do. From what I've found it seems that Java doesn't let you access static methods in an enum like this because it is still being constructed. Does anyone know a better way to do this? Any help is appreciated.

答案1

得分: 0

在您的类中添加一个静态初始化器:

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 }
}
英文:

Add a static initializer to your class:

public enum Number {

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

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

    private final int id;

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

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

发表评论

匿名网友

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

确定