Enum.valueOf对扩展Enum的未知类型的类抛出警告。
给这个:
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>
是什么,我通过使用泛型的意思。我不能这样做,因为这将是一个巨大的级联变化。
回答:
这似乎是编译器错误-应该是错误,而不是警告。
编译方法调用表达式时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 extends
Enum<X>>,就没有大量的强制转换/转换可以将其转换为该形式,因此无法匹配Enum.valueOf
方法的签名。也许javac家伙故意为了使这种代码编译而违反了规范!
以上是 Enum.valueOf对扩展Enum的未知类型的类抛出警告。 的全部内容, 来源链接: utcz.com/qa/416595.html