如何从泛型类型的实例调用values()<e extends =“”enum <e =“”>&gt;?

时间:2016-06-11 16:03:28

标签: java generics enums

public static <E extends Enum<E>> void example(E e){
    e. //what should I put here to get result of values()?
}

我正在尝试调用方法values(),该方法使用带有泛型参数的方法返回enum的值。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

Enum没有values()方法。它稍后由编译器添加到每个Enum子类中(当我们创建自己的enum YourEnum{...}类型时)。因此,我们无法从values()类型调用Enum

可能的解决方案是

E[] values = e.getDeclaringClass().getEnumConstants();

为了安全起见,我们应该使用getDeclaringClass()代替getClass(),因为枚举值可以实现为匿名类,例如TimeUnit

public enum TimeUnit {
    /**
     * Time unit representing one thousandth of a microsecond
     */
    NANOSECONDS {
        public long toNanos(long d)   { return d; }
        public long toMicros(long d)  { return d/(C1/C0); }
        public long toMillis(long d)  { return d/(C2/C0); }
        public long toSeconds(long d) { return d/(C3/C0); }
        public long toMinutes(long d) { return d/(C4/C0); }
        public long toHours(long d)   { return d/(C5/C0); }
        public long toDays(long d)    { return d/(C6/C0); }
        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
    },

在这种情况下

  • TimeUnit.NANOSECONDS.getClass()返回java.util.concurrent.TimeUnit$3(但此匿名类不包含任何枚举值)
  • TimeUnit.NANOSECONDS.getDeclaringClass()返回java.util.concurrent.TimeUnit(包含所有枚举值)。

开始,它也会为我们节省一些麻烦
  • getDeclaringClass返回Class<E>
  • getClass()返回Class<? extends E>

所以

的结果类型
  • getDeclaringClass().getEnumConstants()E[]
  • getClass().getEnumConstants()? extends Enum[]

这允许我们创建循环,而不需要涉及强制转换:

for (E value : e.getDeclaringClass().getEnumConstants()){
    //handle value
}

作为额外内容,您还可以使用Class<E>获取<E extends Enum<E>>(其中EnumSet.allOf(enumClass))的所有值,例如此问题的代码:

EnumSet<E> allOf = EnumSet.allOf(e.getDeclaringClass());

答案 1 :(得分:2)

嗯,clas Class<T>中有一个名为getEnumConstants()的方法可以做到这一点。所以我有这个方法打印出enum常量给定任何枚举值:

public <E extends Enum<E>> void printEnums(E e){
    for(E value : e.getDeclaringClass().getEnumConstants()){
        System.out.println("Value: "+value);
    }
}

要打电话给我,我会使用类似的东西 printEnums(Enum.SOME_VALUE);

虽然我认为以下方法更好,因为它直接将enum的类作为参数:

public static <E extends Enum<E>> void printEnums(Class<E> e){
    for(E value : e.getEnumConstants()){
        System.out.println("Value: "+value);
    }
}

您可以这样调用此方法:printEnums(EnumClass.class);

我知道你不是在问如何打印枚举值,但是上面的这些方法很适合你如何访问给定类型或类的常量。

编辑1:更改了代码。谢谢@JBNizet

编辑2:根据@Tinaki的评论再次更改了代码。注意:这最初是在Pshemo's answer

上解决的