Java JDK 6是否允许非通用遗留代码



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时,您的代码在运行时仍然会失败。

最新更新