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>
=======
谢谢大家的回答。
(T)items[index]
将对象强制转换为T,并且java通用确保它可以成功运行。List<B> bList = (List<B>) aList
是危险的,因此编译器应警告我们,例如将Object强制转换为String。但是即使编译器可以工作,编译器也会阻止我们这样做。List<B> bList = (List<B>)(Object) aList;
编译器理解,由于A
和B
是两种不同的类型,所以的列表A
不能是的列表B
。自行车清单不能是人员清单,反之亦然。因此,演员表被禁止。
每个列表都是一个对象。因此,您始终可以将列表投射到Object
。一旦有了对象,编译器就会知道它是一个对象,所以当您说它确实是的列表时B
,所有编译器都知道这可能是对的,因此它信任您并允许强制转换。接下来,您可能会将其他人放入您的自行车清单,或者为自己制造其他麻烦。这不再是编译器的问题。
您可以将列表强制转换为Object
,但不能将列表强制List<A>
转换List<Object>
为。为什么不?因为这将允许您将任何种类的对象放入应该仅A
包含对象的列表中。请参阅底部链接到的相关问题。
如果我们可以确保其中的每个项目
aList
都是B
,我认为它应该可以工作。
不,不会。强制转换后,您仍然可以使用aList.add(something)
添加不是的内容B
,从而违反bList
了清单的要求B
。在这种情况下,如何将您转换aList
为List<B>
,请参阅链接的问题,那里的答案确实可以解释它,尤其是fracz的答案。
在我看来,Java Designer可以允许我们将列表强制转换为列表,但事实并非如此。…
当然,您可以自由地对语言设计提出不同意见,当然您不会孤单。
…
A a = (A) b
,如果b
不是A
,则会抛出异常。我们可以找到哪个对象导致此结果。如果List<A> aList = (List<A> bList)
可行,则每个项目的Exception都会导致List强制转换错误,我们甚至不知道哪个项目抛出Exception。…
这里有一个根本的区别。如果一个对象是一个A
,它将始终是一个A
。在Java中没有办法可以使它成为除了A
。因此,一旦成功进行了转换,就可以放心,该类型不会给您带来更多不愉快的惊喜。另一方面,即使列表当前仅包含A
对象,也可能在将来的某个时候保留B
,C
或者D
对象或所有对象以及更多。因此,如果Java允许进行强制转换,那么您将冒着各种负面惊喜的风险。我认为这就是他们选择禁止它的原因。我并不是说他们做出了一个完美的决定,只是试图解释至少有一些原因。
…所以Java Designer不允许我们这样做。这是我目前的理解,…
您的理解是正确的。
如果要将当前仅F
包含对象的列表转换为a List<F>
,我建议您将所有元素复制到一个新的List<F>
(例如new)中ArrayList<F>
。这样做并不能阻止您,Java可以帮助您控制列表副本将始终F
仅包含对象。
链接:相关问题:如何将超类型列表转换为子类型列表?对于您的情况,我自己最喜欢的答案是fracz。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句