【问题标题】:Java - Cast ArrayList Up HierarchyJava - 将 ArrayList 向上转换层次结构
【发布时间】:2012-06-06 19:30:37
【问题描述】:
我有一个简单的类结构:
class BaseModel {}
class Performer extends BaseModel {}
我有一个Performers 的集合:
ArrayList<Performer> list = loadPerformerList();
为什么我不能这样做?
functionThatNeedsArrayOfBase( (ArrayList<BaseModel>)list );
或者,我该如何正确地做到这一点?
【问题讨论】:
标签:
java
casting
polymorphism
【解决方案1】:
子集合不是基集合。否则,您可以将基础对象添加到您的子集合中,从而打破假设(反之亦然)。
您可以将函数的参数指定为包含 base 派生类的列表:
void functionThatNeedsArrayOfBase(ArrayList<? extends BaseModel> list) {
//...
}
那么你可以直接通过list而不进行强制转换
【解决方案2】:
试试这个:<? extends BaseModel>,它并没有说明 BaseModel 的哪个子类,只是说它是一个特定的。另请参阅<? super BaseModel>取决于您的需要。
【解决方案3】:
问题在于 ArrayList 的类型安全。你可以在这个StackOverflow Post 上找到几个更详细的解释。简而言之,解决这个问题的方法是让方法接受 <? extends/super Performer> 类型的类。
【解决方案4】:
列表是表演者的ArrayList。
如果 java 允许您将其转换为ArrayList<BaseModel>,那么即使当时的列表也只包含 BaseModel,如果将 Performer 添加到不是 BaseModel 的列表中会发生什么?如果允许,我们就会失去类型安全性。
【解决方案5】:
这不起作用的原因是它允许functionThatNeedsAnArrayOfBase() 向列表添加不同的 BaseModel 子类并破坏原始列表引用。
一个很好的例子是this堆栈溢出问题。
另一个很好的参考是 Josh Bloch 对 Essential Java 中的泛型的介绍。