与泛型的集合

时间:2012-01-19 20:05:45

标签: java arrays generics collections

我有一个关于将泛型与集合一起使用的问题。

ArrayList<Integer> al=new ArrayList<Integer>();

我们知道上述行意味着ArrayList al仅限于保留整数。因此,以下行给出了编译错误:

al.add("wwww");

但我不明白以下行的含义,

ArrayList al=new ArrayList<Integer>();

我们在声明时不在左侧给ArrayList<Integer>。现在,以下行不会给出编译错误:

al.add("wwww");

所以,如果我声明像

ArrayList al=new ArrayList<Integer>();

这意味着a1可以接受任何类型?

这两个声明有什么区别?

6 个答案:

答案 0 :(得分:9)

后一个声明(没有泛型类型)已过时并已弃用。你不应该使用它,它只是为了向后兼容而编译。现代IDE将在此处生成警告。

另请注意,Java仅在编译时强制执行泛型类型,因此从技术上讲,您可以使用一些额外的强制转换将不正确的类型添加到集合中。这就是为什么最好始终保持泛型,不要绕过它们。

答案 1 :(得分:5)

使用此代码:

ArrayList al = new ArrayList<Integer>();
a1.add("www");

编译器会生成一个警告(您应该注意!)但代码将运行且没有错误。从a1提取数据时出现问题。如果您“知道”它包含Integer值,则可以执行以下操作:

Integer val = (Integer) a1.get(index);

但是当您点击"www"元素时,您将获得ClassCastException。泛型用于将此类错误移至编译时,而不是强迫可怜的开发人员跟踪String数组列表中Integer值的结果。

答案 2 :(得分:0)

后一声明基本上与:

相同
ArrayList<Object> al=new ArrayList<Object>();

因此接受任何对象。它不应该被使用,并且可以使用Java向后兼容(Java1.5之前的版本)。

答案 3 :(得分:0)

你应该像这样写ArrayList<Integer> al=new ArrayList<Integer>();以避免使用其他类型添加到列表对象中,因为你会看到错误编译时间。当然你可以使用ArrayList al=new ArrayList<Integer>();但是你必须要小心。换句话说,总是使用第一个:D

答案 4 :(得分:0)

泛型是通过类型擦除实现的:泛型类型信息仅在编译时出现,之后由编译器擦除。因此,ArrayList al声明让编译器接受任何类型。以下是java doc关于此主题的内容。

答案 5 :(得分:0)

这种声明允许向后兼容。因此,您可以将通用列表传递给旧式库中的方法,该库只接受原始列表:

List<Integer> list = new ArrayList<Integer>();
OldStyledClass.method(myArray);

其中方法声明如下:

public static void method(List list)...

在这种情况下,您在java.util.Collections中有一些特殊的实用方法。所以你可以传递给这个方法保护列表:

OldStyledClass.method(Collections.checkedList(myArray, Integer.class));

如果方法将尝试放入其他类型的列表对象,您将获得ClassCastException immediatley。