【问题标题】:Getting Enum from an integer having a Class<? extends Enum> object从具有 Class<? 的整数中获取枚举扩展枚举>对象
【发布时间】:2015-11-02 04:41:12
【问题描述】:

我已经看到this 如果我有一个字符串而不是整数,这是一个非常好的解决方案,但如果我只有特定枚举的类对象和一个整数,我该如何获取特定的枚举常量实例?

【问题讨论】:

    标签: java reflection enums


    【解决方案1】:

    依赖 Java 枚举常量的序数值是不好的做法 - 很容易意外地重新排序它们,这会破坏您的代码。更好的解决方案是简单地提供您自己的整数,您可以使用它来代替:

    public enum MyThing {
      FOO(1),
      BAR(2),
      BAZ(3);
    
      private final int thingId;
    
      private MyThing(int thingId) {
        this.thingId = thingId;
      }
    
      public int getThingId() {
        return thingId;
      }
    }
    

    然后,当您想从MyThing 中获取thingId 时,只需调用getThingId() 方法即可:

    void doSomething(MyThing thing) {
      System.out.printf("Got MyThing object %s with ID %d\n",
        thing.name(), thing.getThingId());
    }
    

    如果您希望能够通过thingId 查找MyThing,您可以自己构建查找表并将其存储在static final 字段中:

      private static final Map<Integer, MyThing> LOOKUP
          = createLookupMap();
    
      private static Map<Integer, MyThing> createLookupMap() {
        Map<Integer, MyThing> lookupMap = new HashMap<>();
        for (MyThing thing : MyThing.values()) {
          lookupMap.put(thing.getThingId(), thing);
        }
        return Collections.unmodifiableMap(lookupMap);
      }
    
      public static MyThing getThingById(int thingId) {
        MyThing result = LOOKUP.get(thingId);
        if (result == null) {
          throw new IllegalArgumentException(
            "This is not a valid thingId: " + thingId);
        }
        return result;
      }
    

    如果你最终有很多枚举类,并且你想对它们中的每一个做类似的事情,你可以为此定义一个接口:

    public interface Identifiable {
      int getId();
    }
    

    然后让你的枚举实现那个接口:

    public enum MyThing implements Identifiable {
      ...
    
      @Override
      public int getId() {
        return thingId;
      }
    }
    

    然后您可以构建一个可重用的机制来根据其 ID 查找 Identifiable 对象。

    【讨论】:

    • 请注意,我事先不知道我的枚举是哪种类型,它甚至可能不是我自己编写的枚举,我在运行时只有他的类类型,我必须能够处理它,所以你的答案是无关紧要的对不起......无论如何谢谢。
    • @OfekRon:这是一个不寻常的要求。你到底想做什么?另外:请注意,此答案不仅适用于您,也适用于未来正在搜索互联网并找到您的问题的人。即使这个答案与您“无关”,它也可能与其他人有关。
    • 不要采取错误的方式,我没有投反对票,因为它是一个很好的答案,但它对我来说不是正确的答案,因此它不会被标记为正确。而且我正在使用反射编写一个数据库助手,所以我不能假设我得到的所有枚举都是由我编写的或者正在实现我的接口。
    • @OfekRon:你还没有回答我的问题:为什么你要这样做? (元问题:世界真的需要另一个 Java 对象关系映射系统吗?但我离题了。)如果你试图存储任意枚举类型的值,并且没有您可以使用定义明确的键,顺序值是错误的存储内容。相反,您应该存储枚举的字符串名称——这是语言保证稳定的标识符。
    • 字符串值也可以改变,它也不安全,在我看来更合理的是字符串值会改变而不是枚举的顺序,我自己总是在末尾添加枚举,但这没关系,我并不是要解决所有可能的极端情况,而且世界可能不需要它,我这样做是为了我自己的使用以及我自己的学习和经验。
    【解决方案2】:

    似乎找到了答案:

    ((Class&lt;? extends Enum&gt;)clazz).getEnumConstants()[index]

    尽管对于任何寻找它的人,您都应该考虑遵循@Daniel Pryden 的回答,因为在我能想到的大多数用例中使用它很可能是不好的做法。

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 2011-10-09
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多