我有一个关于将泛型与集合一起使用的问题。
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
可以接受任何类型?
这两个声明有什么区别?
答案 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。