Enum.valueOf会针对扩展Enum的未知类型类型发出警告? [英] Enum.valueOf throws a warning for unknown type of class that extends Enum?

查看:367
本文介绍了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)

[unchecked] unchecked method invocation: valueOf(java.lang.Class,java.lang.String) in java.lang.Enum is applied to (java.lang.Class,java.lang.String)

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

I don't want to use generics because that's a major change. I don't want to supress. I don't understand why this warning happens. I imagine it is because one cannot extend an Enum type. I get that. But I don't get why the wildcard class is throwing this weird error. Is there a way to fix this without using @SupressWarning or using generics?

修改:要澄清,使用泛型的以下代码会使警告消失。

Edit: To Clarify, the following code using generics makes the warning go away.

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

使用< T> 是我使用泛型的意思。我不能这样做,因为这将是一个巨大的层叠变化。

The usage of <T> is what I mean by using generics. I can't do that because it would be a huge cascading change.

推荐答案

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

This seems to be a compiler bug - it should be an error, not a warning.

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

When compiling the method invocation expression Enum.valueOf(enumClass...), first, capture conversion is applied to the argument types.

<W extends Enum> // a new type parameter 
Class<W> enumClass; // the type of the argument after capture conversion

然后,对<$ c $进行类型推断c> Enum。< T> valueOf(enumClass ...),结果是 T = W

然后,在替换后检查 T 的界限,即 W 是否为子类型枚举< W>

Then, check the bound of T after substitution, i.e. whether W is subtype of Enum<W>.

(此过程与15.12.2.2和15.12.2.3相同;以及15.12 .2.7肯定会产生T = W)

(this process is the same for 15.12.2.2 and 15.12.2.3; and 15.12.2.7 definitely yields T=W)

这里,检查应该失败。所有编译器都知道 W Enum 的子类型,它不能推断 W Enum< W> 的子类型。 (好吧,我们知道这是真的,除非 W = Enum ;但这种知识在子类型规则中不存在,因此编译器不使用它 - 我们可以通过播放来验证这一点这个带有 MyEnum 层次结构的例子,编译器的行为会相同。)

Here, the check should fail. All compiler knows is that W is a subtype of Enum, it cannot deduce that W is a subtype of Enum<W>. (Well, we know that it's true, barring W=Enum; but this knowledge is not present in subtyping rules, so compiler does not use it - we can verify this by playing this example with a MyEnum hierarchy, the compiler will behave the same.)

那么为什么编译器会通过绑定检查只是一个警告?还有另一条规则允许从 Raw 分配到 Raw< X> ,并带有未经检查的警告。为什么允许这是另一个问题(它不应该是),但编译器确实感觉 Raw 可分配给 Raw< X> 。显然这个规则被错误地混合到上面的子类型检查步骤中,编译器认为既然 W Enum ,它就是某种方式还有一个 Enum< W> ,编译器只发出一个警告就传递了子类型检查,违反了规范。

So why does the compiler pass the bound check with just a warning? There is another rule that allows assignment from Raw to Raw<X> with an unchecked warning. Why this is allowed is another question (it shouldn't be), but compiler does have a sense that Raw is assignable to Raw<X>. Apparently this rule is mistakenly mixed into the above subtype checking step, compiler thinks that since W is Enum, it is somehow also a Enum<W>, the compiler pass the subtype checking with just a warning, in violation of the spec.

如果这样的方法调用不应该编译,那么正确的方法是什么?我看不到任何东西 - 只要参数 enumClass 的类型还没有以递归形式 Class< X extends Enum< X> ;> ,没有任何数量的转换/转换可以使其进入该表单,因此无法匹配 Enum.valueOf 的签名方法。也许javac人故意违反规范只是为了让这种代码编译好!

If such method invocation shouldn't compile, what is the correct way? I can't see any - as long as the type of the argument enumClass is not already in the recursive form of Class<X extends Enum<X>>, no amount of castings/conversions can make it into that form, therefore there is no way to match the signature of Enum.valueOf method. Maybe javac guys deliberately violated the spec just to make this kind of code compile!

这篇关于Enum.valueOf会针对扩展Enum的未知类型类型发出警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆