Java泛型理解

时间:2013-12-24 19:17:47

标签: java generics

请您解释一下这里发生了什么以及为什么它没有错误。

List list = new ArrayList<String>();
list.add(1);

对不起,如果已经有类似的问题,我没有正确地提出问题,所以不能google它

5 个答案:

答案 0 :(得分:4)

这里发生的事情暴露了类型擦除的弱点,这是Java泛型背后的机制。更改其泛型类型参数时,ArrayList的实现不会更改:它总是在场景后面的java.lang.Object。

由于在声明列表时没有给接口提供类型参数,编译器允许您添加任何类型的对象,而不仅仅是字符串。特别是,int会自动装入java.lang.Integer,因此值1可以添加到列表中。

答案 1 :(得分:2)

使用raw type List list大致相当于在没有类型检查的情况下使用List<Object>。这种类型的List将接受任何类型的对象。声明

list.add(1);

自动加密Integer以添加到List

答案 2 :(得分:1)

参考文献的泛型很重要。所以

List list = new ArrayList<String>();

毫无意义。一定是

List<String> list = new ArrayList<String>();

如果您没有在泛型中提供引用类型(而不是实际的对象类型),则将其视为Object。所以你可以添加任何内容。

泛型也是编译时的现象。因此,当您说它是如何工作时,它意味着您的代码如何编译而没有编译错误。原因很简单,没有与引用Object关联的泛型,因此被视为Object(默认)。

答案 3 :(得分:1)

Could you please explain me what happens here and why it works without errors.

Type erasure.

Java泛型仅在编译时存在。如果您尝试将int推送到仅在运行时声明为List(默认情况下绑定为Object)的内容,它将正常工作。

答案 4 :(得分:0)

不确定。如果你熟悉C ++,泛型有点像模板(除了少数例外,但不要挖掘那些细节)。泛型的主要思想是代码中的类型安全性,因此清晰度。这非常适合像Java这样的静态类型语言。 List是一个接口,Arraylist从它扩展。因此它的父(超类)是List。列表具有子列表等功能

list.add(1)只是调用列表接口的add方法(在Arraylist中被覆盖)将该元素添加到数组中。

也可以使用:

List<String> list = new ArrayList<String>

关于泛型的精彩文章:http://docs.oracle.com/javase/tutorial/java/generics/