如何使用List <super> </super> </sub>返回List <sub>

时间:2014-11-13 03:47:38

标签: java generics

我有一个返回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()

如果没有对每个元素进行显式强制转换,如何正确执行此操作?

1 个答案:

答案 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;
}