如何l可以从通用类型的实例调用values()< E扩展枚举< E>? [英] How l can call values() from instance of generic type <E extends Enum<E>>?
问题描述
public static <E extends Enum<E>> void example(E e){
e. //what should I put here to get result of values()?
}
我试图调用方法 values()
使用通用参数的方法返回值枚举
。
I am trying to call the method values()
that returns the values of an enum
using this method with generic arguments.
我该怎么做?
推荐答案
枚举
没有 values()
方法。编译器稍后将添加到每个Enum子类(当我们创建自己的枚举YourEnum {...}
类型时)。所以我们无法从枚举
类型调用 values()
。
Enum
doesn't have values()
method. It is added by compiler later to each of your Enum subclasses (when we are creating our own enum YourEnum{...}
type). So we can't invoke values()
from Enum
type.
可能的解决方案是
E[] values = e.getDeclaringClass().getEnumConstants();
为了安全,我们应该使用 getDeclaringClass()
而不是 getClass()
,因为枚举值可以实现为匿名类,如 TimeUnit
To be safe we should use getDeclaringClass()
instead of getClass()
, because enum values can be implemented as anonymous classes like in case of 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
(包含所有枚举值)。
TimeUnit.NANOSECONDS.getClass()
returnsjava.util.concurrent.TimeUnit$3
(but this anonymous class doesn't contain any enum values)TimeUnit.NANOSECONDS.getDeclaringClass()
returnsjava.util.concurrent.TimeUnit
(with contains all of enum values).
因为
-
getDeclaringClass
返回类< E>
-
getClass()
返回?扩展E>
getDeclaringClass
returnsClass<E>
getClass()
returnsClass<? extends E>
所以结果类型
-
getDeclaringClass()。getEnumConstants()
是E []
- 而
getClass()。getEnumConstants()
是?扩展枚举[]
。
getDeclaringClass().getEnumConstants()
isE[]
- while
getClass().getEnumConstants()
is? extends Enum[]
.
这允许我们创建循环,而不需要涉及转换:对于(E值:e.getDeclaringClass())getEnumConstants()){
This allows us to create loop like without need to involve casting:
for (E value : e.getDeclaringClass().getEnumConstants()){
//handle value
}
作为一个额外的,你也可以得到所有通过使用<$ c < E扩展枚举< E>
) $ c> EnumSet.allOf(enumClass)像这个问题的代码一样:
As an extra, you can also get all values from Class<E>
(where <E extends Enum<E>>
) by using EnumSet.allOf(enumClass)
like in case of code from this question:
EnumSet<E> allOf = EnumSet.allOf(e.getDeclaringClass());
这篇关于如何l可以从通用类型的实例调用values()< E扩展枚举< E>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!