为什么我们不能将List <A>强制转换为List <B>

Changchao Liu
List<A> aList = new ArrayList<>();
List<B> bList = (List<B>) aList; //it can't compile successfully
List<B> bList = (List<B>)(Object) aList; //it's ok

List<A>List<B>实际上都是Object []对象,为什么编译器阻止我们投List<A>List<B>

=======

谢谢大家的回答。

  • 如果列表是ArrayList,则它使用Object []保存项目。当我们得到item时,它用于(T)items[index]将对象强制转换为T,并且java通用确保它可以成功运行。
  • List<B> bList = (List<B>) aList是危险的,因此编译器应警告我们,例如将Object强制转换为String。但是即使编译器可以工作,编译器也会阻止我们这样做。
  • 既然编译器阻止了我们这样做,为什么允许我们 List<B> bList = (List<B>)(Object) aList;
奥莱VV

编译器理解,由于AB是两种不同的类型,所以的列表A不能是的列表B自行车清单不能是人员清单,反之亦然。因此,演员表被禁止。

每个列表都是一个对象。因此,您始终可以将列表投射到Object一旦有了对象,编译器就会知道它是一个对象,所以当您说它确实是的列表时B,所有编译器都知道这可能是对的,因此它信任您并允许强制转换。接下来,您可能会将其他人放入您的自行车清单,或者为自己制造其他麻烦。这不再是编译器的问题。

您可以将列表强制转换为Object,但不能将列表强制List<A>转换List<Object>为。为什么不?因为这将允许您将任何种类的对象放入应该仅A包含对象的列表中请参阅底部链接到的相关问题。

如果我们可以确保其中的每个项目aList都是B,我认为它应该可以工作。

不,不会。强制转换后,您仍然可以使用aList.add(something)添加不是的内容B,从而违反bList了清单的要求B在这种情况下,如何将您转换aListList<B>,请参阅链接的问题,那里的答案确实可以解释它,尤其是fracz的答案。

在我看来,Java Designer可以允许我们将列表强制转换为列表,但事实并非如此。

当然,您可以自由地对语言设计提出不同意见,当然您不会孤单。

A a = (A) b,如果b不是A,则会抛出异常。我们可以找到哪个对象导致此结果。如果List<A> aList = (List<A> bList)可行,则每个项目的Exception都会导致List强制转换错误,我们甚至不知道哪个项目抛出Exception。

这里有一个根本的区别。如果一个对象是一个A,它将始终是一个A在Java中没有办法可以使它成为除了A因此,一旦成功进行了转换,就可以放心,该类型不会给您带来更多不愉快的惊喜。另一方面,即使列表当前仅包含A对象,也可能在将来的某个时候保留BC或者D对象或所有对象以及更多。因此,如果Java允许进行强制转换,那么您将冒着各种负面惊喜的风险。我认为这就是他们选择禁止它的原因。我并不是说他们做出了一个完美的决定,只是试图解释至少有一些原因。

…所以Java Designer不允许我们这样做。这是我目前的理解,…

您的理解是正确的。

如果要将当前仅F包含对象的列表转换为a List<F>,我建议您将所有元素复制到一个新的List<F>(例如new)中ArrayList<F>。这样做并不能阻止您,Java可以帮助您控制列表副本将始终F仅包含对象。

链接:相关问题:如何将超类型列表转换为子类型列表?对于您的情况,我自己最喜欢的答案是fracz

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

java从List <B>强制转换为List <A>,其中B扩展了A

add(List <?extended Z>),其中Z是接口。类B扩展了A的实现Z为什么我们不能用List <A>调用add()

当我们知道 List<A> 只包含 B 时,如何将 List<A> 向下转换为 List<B>

为什么不能将List <decimal>强制转换为List <int>?

如果A扩展了B扩展了C,为什么我可以强制转换为A但将ClassCastException强制强制转换为C?

如何解决此java.lang.ClassCastException:[B不能强制转换为java.util.List

将List <A>转换为Map <B,List <A >>

将List [Either [A,B]]转换为Either [List [A],List [B]]

[B不能强制转换为java.sql.Blob

我们不能将int转换为boolean吗?

Java:当B实现A时,从List <B>转换为List <A>?

将list <A *>转换为list <B *>,其中B继承了A

B扩展A时从List <A>转换为List <B>

可以将A => List [B]转换为List [A => B]吗?

为什么我们不能做List <Parent> mylist = ArrayList <child>();

为什么不能将RandomAccessFile强制转换为Inputstream?

将对象强制转换为List <String>

将List <ViewModel>强制转换为ViewModel?

为什么我不能将对象强制转换为正在实现的接口?

为什么我们需要先将double转换为字符串,然后才能将其转换为BigDecimal?

如果我们可以在64位Windows上运行32位可执行文件,为什么不能将其转换?

使用Linq c#将List <A>转换为List <B>

为什么我们不能直接在 List<string> obj= new List<string>() 中添加值?

“不能将Iterable <Element>强制转换为List <Element>”-List是Lister的一种吗?

为什么我不能将此 css 转换为 xpath

Java:为什么我不能将int转换为Long

为什么我不能将其转换为 Int?

为什么我不能将 Dataframe 列转换为整数?

不能将Rest Assured java.util.HashMap强制转换为类java.util.List