当未指定类型参数时,为什么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()
总是返回一个List
, TBlah是什么并不重要。
因为这是generics工作的方式。 不要忘记在声明List
时generics之前它是一个Object
列表。 您应该放置/获取Object
并且您被迫进行强制转换以使用正确的类型获取对象。 实际上它仍然是运行时的Object
列表。
如果没有警告,generics是编译器保证在编译时键入安全性的一种方法。 在运行时,没有List
。 只有List
。 编译器会为您自动执行强制转换,因此您可以在代码中编写String s = list.get(i)
而无需强制转换。
当你声明GenericClass a
你声明一个原始类型(你应该得到一个警告),因此编译器无法知道a.getList()
应该返回什么类型。 所以它使用Object
。 声明GenericClass
现在编译器知道a.getList()
所期望的类型并使用所需的类型。
编辑:应该澄清的是,编译器只有在尊重签名合同时才能知道会发生什么(即GenericClass
)。 如果您不尊重合同(即您使用的是未extends Number
的原始类型),则合同不再适用。 编译器的行为就像没有类型信息一样。 不要忘记编译器还需要保持与在pre-generics时代创建的代码的向后兼容性
你需要一个占位符/引用列表来引用和引用必须是相同的类型。
List