Enum.valueOf会针对扩展Enum的未知类型类型发出警告?

给这个:

Class enumClass = ...; // being passed in from a constructor Enum e = Enum.valueOf(enumClass, aString); // produces a warning that looks like 

[unchecked] unchecked方法调用:java.lang.Enum中的valueOf(java.lang.Class,java.lang.String)应用于(java.lang.Class,java.lang.String)

我不想使用generics,因为这是一个重大变化。 我不想压抑。 我不明白为什么会发生这种警告。 我想这是因为无法扩展Enum类型。 我明白了。 但我不明白为什么通配符类会抛出这个奇怪的错误。 有没有办法解决这个问题,而不使用@SupressWarning或使用generics?

编辑 :要澄清,使用generics的以下代码会使警告消失。

 class Foo<T extends Enum>{ Class enumClass; Enum e = Enum.valueOf(enumClass, aString); } 

的用法就是我使用generics的意思。 我不能这样做,因为这将是一个巨大的层叠变化。

这似乎是一个编译器错误 – 它应该是一个错误,而不是一个警告。

在编译方法调用表达式Enum.valueOf(enumClass...) ,首先,将捕获转换应用于参数类型。

  // a new type parameter Class enumClass; // the type of the argument after capture conversion 

然后,对Enum.valueOf(enumClass...)进行类型推断,结果为T=W

然后,检查替换后T的界限,即W是否是Enum子类型。

(这个过程对于15.12.2.2和15.12.2.3是相同的;而15.12.2.7肯定产生T = W)

在这里,检查应该失败。 所有编译器都知道WEnum的子类型,它不能推断出WEnum的子类型。 (嗯,我们知道这是真的,除非W=Enum ;但这种知识在子类型规则中不存在,因此编译器不使用它 – 我们可以通过使用MyEnum层次结构来MyEnum此示例来validation这一点,编译器将表现相同。)

那么为什么编译器仅通过警告传递绑定检查? 还有另一个规则允许使用未经检查的警告从RawRaw进行分配。 为什么允许这是另一个问题(它不应该是),但编译器确实认为Raw可以赋给Raw 。 显然这个规则被错误地混合到上面的子类型检查步骤中,编译器认为既然WEnum ,它也是一个Enum ,编译器只通过警告传递子类型,违反了规范。

如果这样的方法调用不应该编译,那么正确的方法是什么? 我看不到任何 – 只要参数enumClass的类型不是已经在Class>的递归forms中,没有任何数量的转换/转换可以使它进入该forms,因此有无法匹配Enum.valueOf方法的签名。 也许javac家伙故意违反规范只是为了让这种代码编译!

EnumClass都是通用的。 所以如果你不想要任何警告:

 class Foo>{ Class enumClass; T e = Enum.valueOf(enumClass, str); } 

或者您可以使用通用方法:

 public > T getEnumValue(Class clazz, String name) { T e = Enum.valueOf(clazz, name); return e; } 

但是如果你不使用generics,那么你使用的是原始类型,因此编译器会发出警告 – 除了抑制它们之外别无选择。

如果你想一想valueOf里面发生了什么,你会发现你的代码不可能像写的那样工作。 Enum.valueOf需要一个实际枚举类的实例作为参数; 然后简单地遍历该类的values()以寻找匹配。

由于类型擦除 ,generics将无法在您的代码中使用。 没有实际类型传递到Enum.valueOf