10

为什么以下不编译?+编译器对打印行中的符号给出错误。

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 是 a HashMap<Integer,Integer>,它根本不应该依赖于类型<T>。为什么编译器拒绝这个?在第一行删除<T>允许编译,但我不明白为什么这不应该工作。

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

4

2 回答 2

8

我没有解释为什么,但行为似乎确实是正确的定义。Java 语言规范的第 4.8 节“原始类型”明确指出:

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

在您的示例中,原始类型 C 是Test(与Test<Object>orTest<Integer>或诸如此类相反),非静态字段Mm. 作为上述规则的结果,类型t.m是原始类型HashMap,而不是HashMap<Integer, Integer>,所以返回类型t.m.get(Object)Object而不是Integer

于 2012-09-27T02:09:51.380 回答
1

只需更换您的线路:

Test t = new Test();

经过:

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

这将起作用。

于 2012-09-27T01:59:40.403 回答