如果我在编译时不知道该类,如何获得Enum的值?
我正在尝试执行以下操作:
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, String) of type Enum 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>
有人能告诉我我做错了什么吗?
鉴于演员不会真正检查事物,我会选择完全原始的版本:
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); } } }
问题是你有两个?
他们可能是不同的,他们必须是一样的。
你要么必须使用非generics声明generics类似的
public static > T val(Class cls) { if(cls.isEnum()) { // is redundant when the compiler checks this. @SuppressWarnings("unchecked") Class enumClass = (Class ) cls; T val = Enum.valueOf(enumClass, "NAME1"); return val; } return null; }
但是,调用这种方法也是一个噩梦。 ;)
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和抽象控制流来做一些聪明的事情。
注意:
- 反思几乎总是一个非常糟糕的主意。
- 无需未经检查的警告或抑制这些有效警告。
- 不需要rawtypes(有拼写和语义)警告或抑制那些有效的警告。
- 不需要毫无根据的咆哮。
- 没有必要低估这个答案。
使用原始类型是好的。 虽然Java不愿意添加原始类型,但它已被certificate是必要且必不可少的,除了向后兼容性问题。
如果没有原始类型,要以理论上完美的方式解决您的问题,Java必须更加复杂。 它可能需要一个类型变量变量。 那时,代码不再取悦人类,而是取悦机器。 (我们可能已经在这一点上,考虑了所有无法理解的generics代码)
class EnumValues> { public static
> P [] getValues( Class
keyType) { return keyType.getEnumConstants(); } }
用法:
Class cls = Thread.State.class; for( Enum en : EnumValues.getValues( cls)) System.out.println( en.name());