我有一个返回List<Super>
的方法。
说
List<Super> myMethod();
调用该方法时,我想将返回的列表强制转换为List<Sub>
,因为它知道其运行时类型为List
Sub
。
我知道List<Sub> subs = (List<Sub>) myMethod()
不会起作用,因为泛型是不变的。
但是,List<? super Sub> subs = myMethod()
有效,编译时类型变为List<Object>
,因此subs.get(0).mySubMethod()
无法正常工作。
我最终得到的是我必须明确地将其转换为((Sub) subs.get(0)).mySubMethod()
如果没有对每个元素进行显式强制转换,如何正确执行此操作?
答案 0 :(得分:6)
最短的版本是:
List<Sub> subs = (List) myMethod();
List
是&#34;原始类型&#34 ;;您可以在没有演员的情况下从List
转换为任何List<...>
。
请注意,这是以一种根本不正确的方式绕过类型系统;该列表被构造为ArrayList<Super>
(或类似的),因此欺骗编译器让您使用List<Sub>
类型的引用引用它实际上是不正确的,即使它发生了所有列表元素都是Sub
类型。 (对于msandiford上面的较长版本来说也是如此;它可能看起来更加通用,但它实际上只是做同样根本不正确的事情的另一种方式。)
但是,由于类型擦除,你通常可以逃脱它。
一种正确的方法是使方法本身通用:
<T extends Super> List<T> myMethod(final Class<T> clazz) {
final List<T> ret = Collections.checkedList(new ArrayList<T>(), clazz);
// ... add elements to ret ...
return ret;
}