我认为这应该是合法的,但编译器在这一点上不同意我的看法
通常,当人类和编译器不同意时,站在编译器一边是安全的。而不是欺骗编译器,您应该首先了解它为什么不允许转换。
考虑一下:你制作一个List<B>
,像这样:
List<B> listB = new ArrayList<B>();
到目前为止,每个人都很高兴。现在让我们做你认为正确的事情:
// This does not compile, but let's pretend that it does
List<A> listA = (List<A>)listB;
在这一点上,我们拥有listA
这完全是我们的!让我们玩一下:假设我们有另一个类C
扩展A
. 我们可以这样做吗?
listA.add(new C()); // Why not? The compiler should allow it!
但是等等,你看到我们做了什么吗?我们listB
包含一个C
现在!这就是编译器不允许转换的原因;这也是为什么在您尝试向列表中添加任何内容时您的代码不安全的原因。
要解决此问题,您可以使用通配符:List<? extends A>
. 但是,这会将您的列表限制为只读访问。如果您必须允许编写(并且您知道您将只设置正确的内容),请改用非泛型List
。