java JDK 6支持旧的非泛型集合吗?还是在运行时破坏现有代码?
如果它确实支持它,你必须启用它吗?
例如:
List<Integer> list = new ArrayList<Integer>();
list.add(5);
Alpha a = new Alpha();
a.insert(list);
for (Integer integer : list) {
System.out.println(integer);
}
非通用(遗留代码):
public class Alpha {
public void insert(List list) {
list.add(new String("50"));
}
}
这编译得很好,但在运行时会中断。我以为它会运行得很好,编译器只会警告你。
泛型在某种程度上只存在于编译时。(不完全是这样;仍然到处都是元数据,但对象类型本身没有受到影响,特别是支持ArrayList
的数组仍然是Object[]
。这在这里非常重要。)您可以总是使用泛型类型,就像它是非泛型类型一样-编译器会警告您,但类本身无法阻止您这样做。
您的代码中断是因为您在这里隐式地将数组的每个元素强制转换为Integer:
for (Integer integer : list) {
System.out.println(integer);
}
您期望在执行时如何处理?需要明确的是,编译后的代码大致相当于:
for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
Integer integer = (Integer) list.next();
System.out.println(integer);
}
想象一下,你生活在一个没有泛型的世界里,想想如果你在列表中有一个String
(事实上,多亏了Alpha
,你已经有了)会怎么办。完全相同的事情(ClassCastException
)将在和泛型中发生。
编译器会对此发出警告。
使用-Xlint选项运行javac以获取完整的详细信息。
警告:〔unchecked〕unchecked调用将(E)添加为原始类型java.util.List的成员list.add(新字符串("50"));
如果你想使用非类型(原始类型)列表,那么只需使用类似的遗留代码创建一个:
List list = new ArrayList();
但是当您将添加到List的String强制转换为Integer时,您的代码在运行时仍然会失败。