如果我在编译时不知道该类,如何获得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());