【问题标题】:Java generics for Enum types枚举类型的 Java 泛型
【发布时间】:2011-05-01 23:40:51
【问题描述】:

我正在尝试编写一个 Java 类,其中一部分需要将未知枚举的值映射到另一个类。我的类包含一个字段private Map<? extends Enum, Unit> myMap,并使用工厂方法createMyClass进行初始化:

public static MyClass <T extends Enum> myClass createMyClass(Class<T> x) {
    MyClass theClass = new MyClass() //constructor is private
    //...
    myMap = new HashMap<T, Unit>();
    for(T t : x.getEnumConstants())
        myMap.put(t, theClass.new Unit(t));
    //...
}

Unit 类是(据我所知,必须是)MyClass 的内部类。当我将它放入 NetBeans 时,它会抱怨以下消息:

接口java.util.Map&lt;K,V&gt;中的方法put不能应用于给定类型
必需:捕获? extends java.lang.EnumMyClass.Unit 中的#4
找到:TMyClass.Unit

我理解(或者至少我认为我理解)集合需要非常小心地使用通配符以保持类型安全,但我想不出T extends Enum 为何无法匹配? extends Enum

【问题讨论】:

    标签: java generics collections wildcard enumeration


    【解决方案1】:

    尝试将您的方法声明更改为:

    public static <T extends Enum<T>> MyClass createMyClass(Class<T> x) {
    }
    

    【讨论】:

      【解决方案2】:

      Map&lt;? extends Enum, Unit&gt; 的意思是“关键是一些扩展 Enum 的特定类,但我不知道是哪一个”。而且由于你不知道它是哪个类,所以你不能向这样的 Map 添加任何东西,你只能从中获取元素并确定它们是 Enums。

      您可能应该将该字段声明为 Map&lt;Enum, Unit&gt; - 它允许所有 Enum 子类就好了。

      这似乎是对 Java 枚举最常见的误解——人们看到? 通配符并认为他们必须使用它来允许子类。

      【讨论】:

      • 我将其更改为? extends Enum 的原因是,将其保留为Enum 会产生另一个错误,指出Tincompatible typeEnum,并建议我使用演员表.由于这样的演员表看起来很可疑,我尝试使用? extends。作为补充问题,我是否必须将HashMap&lt;T,Unit&gt; 转换为HashMap&lt;Enum,Unit&gt;
      • @Actorclavilis:我认为你的问题的原因是 Enum 本身就是一个泛型类。看看 EnumMap,它可能会让事情变得更简单,而且肯定会更快。
      • 沿着这些思路,将T 声明为&lt;T extends Enum&lt;T&gt;&gt; 将解决该问题。
      【解决方案3】:

      您可以阅读此Generics Tutorial。它解释了为什么这在第 4 节(通配符)中不起作用。

      据我所知,? extends Enum 可以是 any 枚举,而不仅仅是 T 或 T 的子类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多