我正在尝试执行以下操作:
Class<?> cls = unknownClass;
if(cls.isEnum()){
@SuppressWarnings("unchecked")
Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) cls;
Object val = Enum.valueOf(enumClass, "NAME1");
}
但是我收到以下错误:
Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is
not applicable for the arguments (Class<capture#5-of ? extends Enum<?>>, String).
The inferred type capture#5-of ? extends Enum<?> is not a valid substitute for
the bounded parameter <T extends Enum<T>>
有人能告诉我我做错了吗?
答案 0 :(得分:20)
鉴于演员不会真的正在检查事情,我会选择完全原始的版本:
if (cls.isEnum()){
@SuppressWarnings("unchecked")
Object val = Enum.valueOf(cls, "NAME1");
}
这似乎有效。完整的例子:
public class Test
{
enum Foo
{
BAR, BAZ
}
public static void main(String[] args)
{
@SuppressWarnings("rawtypes")
Class cls = Foo.class;
if (cls.isEnum())
{
@SuppressWarnings("unchecked")
Object value = Enum.valueOf(cls, "BAR");
System.out.println(value);
}
}
}
答案 1 :(得分:7)
问题是你有两个?
,它们可能不同,而且它们必须相同。
您必须使用非泛型声明类似
的泛型类型public static <T extends Enum<T>> T val(Class<T> cls) {
if(cls.isEnum()) { // is redundant when the compiler checks this.
@SuppressWarnings("unchecked")
Class<T> enumClass = (Class<T>) cls;
T val = Enum.valueOf(enumClass, "NAME1");
return val;
}
return null;
}
然而,调用这种方法也是一个噩梦。 ;)
答案 2 :(得分:4)
Class.getEnumConstants
将提供所有枚举,然后您就可以找到您感兴趣的枚举。
修改Jon的代码:
public class Test {
private enum Foo {
BAR, BAZ
}
public static void main(String[] args) {
Class<?> cls = Foo.class;
if (cls.isEnum()) {
for (Object constant : cls.getEnumConstants()) {
Enum<?> enumConstant = (Enum<?>)constant;
if (enumConstant.name().equals("BAR")) {
System.out.println(constant);
break;
}
}
}
}
}
在Java SE 8中,您可能能够使用lambda和抽象控制流来做一些聪明的事情。
注意:
答案 3 :(得分:1)
使用原始类型是好的。虽然Java不愿意添加原始类型,但除了向后兼容性问题之外,它已被证明是必要且必不可少的。
如果没有原始类型,要以理论上完美的方式解决您的问题,Java必须更加复杂。它可能需要一个类型变量变量。那时,代码不再取悦人类,而是取悦机器。 (考虑到所有无法理解的泛型代码,我们可能已经在这一点上了)
答案 4 :(得分:-1)
class EnumValues<P extends Enum<P>>
{
public static <P extends Enum<P>> P [] getValues( Class<P> keyType)
{
return keyType.getEnumConstants();
}
}
用法:
Class cls = Thread.State.class;
for( Enum en : EnumValues.getValues( cls))
System.out.println( en.name());