当前位置: 首页 > 面试题库 >

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

宗意蕴
2023-03-14
问题内容

给这个:

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家伙故意为了使这种代码编译而违反了规范!



 类似资料:
  • 问题内容: 我想为此创建一个扩展名,仅影响… 我了解这些说明是相关的,但不确定如何: 扩展通用类型时,不提供类型参数列表作为扩展定义的一部分。而是在扩展程序的正文中提供原始类型定义的类型参数列表,并且原始类型参数名称用于引用原始定义的类型参数。 基本上,我正在尝试使用此方法: 在没有参数的情况下采取行动…这可能吗? 问题答案: Swift 3.1更新 从Swift 3.1(Xcode 8.3 be

  • 问题内容: 我试图在这样的泛型类中创建一个常规的RuntimeException: 这段代码使我对这个词的错误说法。 这个RuntimeException与我的类通用有什么关系? 问题答案: Java不允许Throwable的通用子类。而且,非静态内部类可以通过其外部类的类型参数有效地进行参数化(请参见Oracle JDK Bug 5086027 )。例如,在您的示例中,内部类的实例具有form类

  • 问题内容: 我正在尝试在一个抽象类中创建一个抽象方法,该抽象类将自己的Enum作为参数。但是我也希望枚举是通用的。 所以我这样宣布: 在实现中,我列举了一个枚举: 并且方法声明变为: 但是,如果我这样做: 我无法访问并显示错误消息: 我做了这样的解决方法: 但是我想知道是否有可能无法通过我的解决方法? 问题答案: 在您的方法实现中,不是枚举,而是类型参数(通常称为)。因此,它掩盖了与已经说过的ax

  • 问题内容: Java是否可以让类扩展泛型,以便您可以将方法注入通过代码传递的任何类中?(或者是否有其他方法可以使用Java将方法注入或重写到现有类中?) 我所说的“扩展通用类型”是这样的(类“ Textended GameObject”属于游戏,可能不会更改,并且是未知的,因为它是在运行时(从其他mods)加载到游戏中的): onTick由GameEngine调用,通过这种方式,我可以将每个现有的

  • 我想创建一个自定义的树数据结构,只有节点,我可以迭代他们。然后,我可以扩展这个类,并有非常基本的树 我已经开始工作了,但是当我试图扩展Node类时,问题就来了。对于扩展类,继承的迭代器方法仍然返回节点迭代器,这意味着我每次都要强制转换。下面是我遇到的问题的一个基本示例。让我们建立一个包含整数的树: 是否有一种简单的方法可以解决这个问题,而不需要将iterator()方法从Node类复制到Integ

  • 问题内容: 是否可以为特殊/构造的泛型类型扩展泛型类?我想使用一种方法来扩展Int Arrays,以计算其元素的总和。 例如 问题答案: Swift 5.x: