泛型类中擦除了所有HashMap类型值?

时间:2012-09-27 01:40:44

标签: java generics compiler-errors

为什么以下不能编译?编译器为打印行中的+符号提供错误。

public class Test<T> {
  HashMap<Integer,Integer> m = new HashMap<Integer, Integer>();
  public static void main(String[] args) {
    Integer zero1 = 0;
    Integer zero2 = 0;
    Test t = new Test();
    t.m.put(1,zero1);
    t.m.put(2,zero2);
    System.out.println(t.m.get(1)+t.m.get(2)==t.m.get(2));
  }
}

我理解类型擦除,但m是HashMap<Integer,Integer>,它根本不应该依赖于类型<T>。为什么编译器会拒绝这个?删除第一行中的<T>允许编译,但我不明白为什么这不应该也能正常工作。

这是编译器错误还是这种行为背后有任何逻辑?

2 个答案:

答案 0 :(得分:8)

我没有解释为什么,但行为确实似乎是正确的。§4.8 "Raw Types" of the Java Language Specification明确指出:

  

构造函数的类型(§8.8),实例方法(§8.4§9.4)或非静态字段(§8.3M不从其超类或超接口继承的原始类型C是原始类型,对应于在与C对应的泛型声明中擦除其类型。

在您的示例中,原始类型C为Test(与Test<Object>Test<Integer>或其他内容相对),非静态字段M为{{1 }}。作为上述规则的结果,m的类型是原始类型t.m,而不是HashMap,因此HashMap<Integer, Integer>的返回类型为t.m.get(Object)而不是Object

答案 1 :(得分:1)

只需更换您的专线:

Test t = new Test();

由:

Test<Integer> t = new Test<Integer>();

这将有效。