有没有办法将某些父类(super class)型列表转换为子类型列表?看起来这应该是可能的,因为如果您创建封装通用列表的非通用类型,则可以按预期进行转换。例如:
class Foo {}
class Bar extends Foo {}
public class MyClass {
public static void main(String[] args) {
ArrayList<Foo> fooList = new ArrayList<>();
fooList.add(new Bar());
// No can do. "Cannot cast from ArrayList<Foo> to ArrayList<Bar>"
// ArrayList<Bar> barList = (ArrayList<Bar>) fooList;
// Bar bar = barList.get(0);
FooList newAndImproveFooList = new FooList();
newAndImproveFooList.add(new Bar());
BarList barList = (BarList) newAndImproveFooList;
barList.get(0);
}
}
class FooList {
private ArrayList<Foo> list = new ArrayList<>();
// Simple delegates
public void add(Foo foo) { list.add(foo); }
public Foo get(int index) { return list.get(index); }
}
class BarList extends FooList {
public Bar get(int index) { return (Bar) super.get(index); }
}
这段代码的目的是表明这个转换问题可以“轻松”解决。当然,我们可以转换不同类型的数组(因此 FooList
可能包含不属于 Bar
的 Foo
这不是问题。
似乎这个问题的唯一解决方案是不使用泛型,但是您必须为需要创建列表的每种类型创建此列表的实例,这正是泛型所面临的问题旨在解决。
我们可以强制转换对列表的每个访问,但是程序的当前布局(并且不能轻易更改它)将导致数千次强制转换,就好像我们可以强制转换列表一样,我们只需要一个在一些地方有几个 Actor 。
我们无法复制该列表,因为它在某些地方被修改了。
最佳答案
最简单的方法是做相当于
的事情ArrayList<Bar> barList = (ArrayList<Bar>) (ArrayList<? extends Foo>) fooList;
这将引发一堆有关未经检查的强制转换的编译器警告。编译器试图警告您这不会带来任何好处。通过执行此转换,如果您要将 barList
的元素用作 Bar
,您将丢失所有类型信息,并导致 ClassCastException
异常。对象。
您可以将 Bar
项添加到 barList
,但无法将它们作为 Bar
对象检索,因为它们是 Foo
对象。
表演 Actor 是合法的,就像
Integer value = (Integer) (Object) "I'm not an Integer.";
但这并不意味着它是安全的。 明智地使用它。
关于java - 将参数化类转换为参数的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25493402/