奇怪的JDK行为,应该编译吗?

时间:2013-04-10 12:42:51

标签: generics compilation java

import java.util.*;

public class Main <T> {

    public void guru(List<Integer> list) {
        System.out.println("INteger");
   }

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        new Main().guru(list);
    }
}

在我看来,调用

guru(List<String>); //no type erasure during compiling...

应该导致编译失败。

如果我们用以下方法创建对象会发生什么:

new Main<Integer>() //or any other type

谁能告诉我这里发生了什么? JDK中的错误或没有参数的实例化参数化对象可能会导致此类问题,为什么?

我可以补充说,如果我们将主要定义更改为:

public class Main {

编译失败,正如预期的那样。

1 个答案:

答案 0 :(得分:6)

问题在于:

new Main().guru(list);
       ^^^^

您使用Main的原始版本(没有泛型),因此忽略所有通用信息。你应该得到编译器警告。

如果您尝试:

new Main<SomeType>().guru(list);

您应该收到编译错误。

更确切地说,当使用原始类型:new Main()时,会执行类型擦除,这不仅会删除类型本身的通用信息,还会also from its methods

  

原始类型C [...]的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型是对应的原始类型在与C相对应的通用声明中删除其类型。