这似乎是编译器错误-应该是错误,而不是警告。
编译方法调用表达式时Enum.valueOf(enumClass...),首先,将捕获转换应用于参数类型。
<W extends Enum> // a new type parameter Class<W> enumClass; // the type of the argument after capture conversion
然后,对进行类型推断Enum.<T>valueOf(enumClass...),结果为T=W。
然后,检查T替换后的边界,即是否W为的子类型Enum<W>。
(此过程对于15.12.2.2和15.12.2.3相同;并且15.12.2.7肯定会产生T = W)
在这里,检查应该失败。所有编译器都知道是W的子类型Enum,它不能推断出W是的子类型Enum<W>。(好吧,我们知道这是真的,禁止W=Enum;但是子类型化规则中没有这种知识,因此编译器不会使用它-我们可以通过在MyEnum层次结构中播放此示例来验证这一点,编译器的行为将相同。)
那么,为什么编译器仅通过警告就通过了边界检查?还有另一个规则,允许从Raw到的分配Raw<X>带有未选中的警告。为什么允许这样做是另一个问题(不应该这样),但是编译器确实可以Raw分配给Raw<X>。显然,此规则被错误地混入了上面的子类型检查步骤,编译器认为既然W是Enum,也是某种程度上Enum<W>,编译器仅通过警告就通过了子类型检查,这违反了规范。
如果不应该编译这种方法,正确的方法是什么?我看不到任何东西-只要参数的类型enumClass尚未为的递归形式Class<X extendsEnum<X>>,就没有大量的强制转换/转换可以将其转换为该形式,因此无法匹配Enum.valueOf方法的签名。也许javac家伙故意为了使这种代码编译而违反了规范!
解决方法给这个:
Class<? extends Enum> enumClass = ...; // being passed in from a constructorEnum e = Enum.valueOf(enumClass,aString); // produces a warning that looks like
[未检查]未检查的方法调用:java.lang.Enum中的valueOf(java.lang.Class,java.lang.String)应用于(java.lang.Class,java.lang.String)
我不想使用泛型,因为这是一个重大更改。我不想压抑。我不明白为什么会发生此警告。我想这是因为无法扩展Enum类型。我明白了。但是我不明白为什么通配符类会抛出这个奇怪的错误。有没有一种方法可以解决而不使用@SupressWarning或不使用泛型?
编辑 :为澄清起见,以下使用泛型的代码使警告消失。
class Foo<T extends Enum<T>>{ Class<T> enumClass; Enum e = Enum.valueOf(enumClass,aString);}
的用途<T>是什么,我通过使用泛型的意思。我不能这样做,因为这将是一个巨大的级联变化。