【问题标题】:Compiler warning about raw type when calling Map#put()调用 Map#put() 时有关原始类型的编译器警告
【发布时间】:2015-12-19 11:27:56
【问题描述】:

我构建了一个接收泛型对象的 Java 类;

class only 字段设置为:

private Map map = new HashMap<T,Integer>();

我的问题是,在我编写的某些方法中,当我为 HashMap 对象调用 put 方法时,编译器警告我并显示以下消息:

类型安全:方法put(Object, Object)属于原始类型HashMap。应该参数化对泛型类型Map&lt;K,V&gt; 的引用

我更喜欢避免编译器警告,因为它可能以运行时错误结束。

如果您能向我解释这个消息以及我需要做些什么来消除它,我会很高兴。

我写的方法是:

public void addItem(T item) {
    if (this.map.containsKey(item)) {
        this.map.put(item, (int)this.map.get(item) + 1);
    }
    else {
        this.map.put(item, 1);
    }
}

在这里你可以看到编译器抱怨的地方:

【问题讨论】:

  • 我不相信你真的得到了你所说的信息。我相信实际上你得到了“类型安全:方法 put(Object, Object) 属于原始类型 Map”。

标签: java generics compiler-warnings


【解决方案1】:

改变

private Map map = new HashMap();

private Map<Type1, Type2> map = new HashMap<>();

其中Type1Type2 是地图的keyvalue 的类名(分别)

例如,要声明由Integers 索引的String 值的映射: (注意不能使用原始类型)

private Map<Integer, String> map = new HashMap<>();

您的方法的缺点可以在您方法的第 3 行看到,其中需要向下转换。显然,如果键值对已被不同的值类型替换,这可能会导致 ClassCastException。 (在这种情况下,您向下转换为 int,这是无效的)

通过参数化地图,您强制将对象的类型包含在其中(或要使用的键的类型)

【讨论】:

  • 您的回答是正确的,但恐怕它并不能真正帮助 OP。您是在给他鱼而不是给他钓鱼竿...我希望实际答案真正向他解释了错误消息背后的原因
【解决方案2】:

map 的声明类型是未参数化的接口,编译器会检查声明的类型,而不是实际的类型。

【讨论】:

    【解决方案3】:

    如果您想正确使用泛型,仅在实例化中使用它们是不够的(= 通过调用new 运算符创建新对象)new HashMap&lt;T,Integer&gt;(),但您还应该声明 使用泛型的变量:

    private Map<T,Integer> map = new HashMap<T,Integer>();
    

    从 Java 7 开始,您不必在实例化中重复类型,因为编译器足够聪明,可以从声明中推断(=推断)正确的类型。这意味着你可以只写

    private Map<T,Integer> map = new HashMap<>();
    

    &lt;&gt; 的构造根据其形状称为菱形运算符

    您的编译器抱怨使用没有泛型的Map,这被称为原始类型

    我相信您没有正确复制警告消息。我的编译器说

    类型安全:方法 put(Object, Object) 属于原始类型 Map

    注意Map,而不是HashMap。因为编译器(通常)无法知道您分配给 map 变量的实际实例。因此,编译器抱怨的是 variable map 的原始类型,而不是它的实际 content

    并且编译器应该已经在声明中抱怨(除非你以某种方式抑制它)

    private Map map = new HashMap<T,Integer>();
    

    Map 是原始类型。对泛型类型 Map 的引用应该被参数化

    这正是我写的。从出现的第一行开始阅读警告总是好的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 2018-10-16
      相关资源
      最近更新 更多