Enum.valueOf对扩展Enum的未知类型的类抛出警告。

给这个:

Class<? extends Enum> enumClass = ...; // being passed in from a constructor

Enum 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>。显然,此规则被错误地混入了上面的子类型检查步骤,编译器认为既然WEnum,也是某种程度上Enum<W>,编译器仅通过警告就通过了子类型检查,这违反了规范。

如果不应该编译这种方法,正确的方法是什么?我看不到任何东西-只要参数的类型enumClass尚未为的递归形式Class<X extends

Enum<X>>,就没有大量的强制转换/转换可以将其转换为该形式,因此无法匹配Enum.valueOf方法的签名。也许javac家伙故意为了使这种代码编译而违反了规范!

以上是 Enum.valueOf对扩展Enum的未知类型的类抛出警告。 的全部内容, 来源链接: utcz.com/qa/416595.html

回到顶部