当未指定类型参数时,为什么Javagenerics原始类会擦除所有generics对象?

如果我有课:

public class GenericClass { public List getList() { return null; } } 

当我尝试从另一个类使用该方法时:

 public class OtherClass { public void test() { GenericClass a = null; for (String s : a.getList()) { } } } 

为什么a.getList()返回List直到我将for循环上面的行更改为:

 GenericClass a = null; 

此时a.getList()返回一个List就像它应该做的那样?

编辑:我不明白为什么getList()指定的getList()应该受到如何声明我的变量’a’的影响。 getList()总是返回一个ListTBlah是什么并不重要。

因为这是generics工作的方式。 不要忘记在声明List时generics之前它是一个Object列表。 您应该放置/获取Object并且您被迫进行强制转换以使用正确的类型获取对象。 实际上它仍然运行时的Object列表。

如果没有警告,generics是编译器保证在编译时键入安全性的一种方法。 在运行时,没有List 。 只有List 。 编译器会为您自动执行强制转换,因此您可以在代码中编写String s = list.get(i)而无需强制转换。

当你声明GenericClass a你声明一个原始类型(你应该得到一个警告),因此编译器无法知道a.getList()应该返回什么类型。 所以它使用Object 。 声明GenericClass a = null; 现在编译器知道a.getList()所期望的类型并使用所需的类型。

编辑:应该澄清的是,编译器只有在尊重签名合同时才能知道会发生什么(即GenericClass )。 如果您不尊重合同(即您使用的是未extends Number的原始类型),则合同不再适用。 编译器的行为就像没有类型信息一样。 不要忘记编译器还需要保持与在pre-generics时代创建的代码的向后兼容性

你需要一个占位符/引用列表来引用和引用必须是相同的类型。

List x = a.getList();