5
4

4 回答 4

13

苹果水果,但苹果列表不是水果列表。

如果是,你可以在苹果列表中放一根香蕉

于 2013-01-15T12:14:09.007 回答
3

直接转换列表是不好的,因为它颠覆了 Java 类型系统。强制转换总是会成功,但程序可能会ClassCastException在您稍后检索项目时失败,此时错误的来源可能不清楚。

通常,您希望程序在尽可能接近错误源的位置失败。如果你强制转换列表,它可能会在有人真正尝试访问元素之前传递一段时间,到它抛出 aClassCastException时,可能真的很难追踪到那个强制转换(至少比 if更难)该程序在演员表中失败)。

从您的评论看来,您确定其中的所有listA内容实际上都是 aB在这种情况下,我建议:

List<B> listB = new ArrayList(listA.size());
for (A a : listA) {
  if (a == null || a instanceof B) {
    listB.add((B) a);
  } else {
    //Either ignore or throw exception
  }
}
于 2013-01-15T12:58:49.893 回答
2

为此,您必须了解List<A>andList<B>是两种不同的类型,没有层次关系,即使AB是层次相关的。即使B是 的子类A,将 a 强制转换List<B>为 a也是不好的,因为它可以允许您将(但不是) 的List<A>实例添加到该列表中,并且编译器会很乐意这样做,即使它与实际的 (运行时) 不一致集合的类型。AB

我不知道你可以在 Java 中规避这一点,但如果你能做到,那只是因为类型擦除:因为 Java 创建了一个类,例如List<Object>,对于该泛型类的不同“实现”,它只是在你的代码中添加强制转换在编译它之前。这与(比如说)C# 形成对比,C# 实际上List<T>只使用作为“编译”模板(称为“通用定义”)来按需创建具体类型。

于 2013-01-15T12:17:29.157 回答
0

泛型的工作方式有所不同,因此list< B >不是list< A >类型,尽管BA的类型。

于 2013-01-15T12:53:14.070 回答