【问题标题】:Strange JDK behaviour, should it compile?奇怪的JDK行为,它应该编译吗?
【发布时间】:2013-04-10 12:42:50
【问题描述】:
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中的错误或实例化没有参数的参数化对象可能会导致此类问题,为什么?

如果我们将 Main 定义更改为:

public class Main {

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

【问题讨论】:

    标签: generics compilation java


    【解决方案1】:

    问题出在这里:

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

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

    如果你尝试:

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

    你应该得到一个编译错误。

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

    构造函数的类型(第 8.8 节)、实例方法(第 8.4 节、第 9.4 节)或非静态字段(第 8.3 节)原始类型 C [...] 的原始类型对应于在对应于 C 的泛型声明中擦除其类型。

    【讨论】:

    • 非常感谢,我认为原始版本意味着只有实际参数被忽略(在本例中为 )。这解释了一切。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多