例如,假设你有两个类:

public class TestA {}
public class TestB extends TestA{}

我有一个返回List<TestB>的方法,我想将该列表中的所有对象强制转换为TestB,以便最终得到List<TestB>。


当前回答

这应该是可行的

List<TestA> testAList = new ArrayList<>();
List<TestB> testBList = new ArrayList<>()
testAList.addAll(new ArrayList<>(testBList));

其他回答

这应该是可行的

List<TestA> testAList = new ArrayList<>();
List<TestB> testBList = new ArrayList<>()
testAList.addAll(new ArrayList<>(testBList));

简单地转换为List<TestB>就可以了;但它不起作用,因为您不能将一个参数的泛型类型强制转换为另一个参数。然而,你可以通过一个中间通配符类型进行强制转换,这是允许的(因为你可以强制转换到通配符类型,只是有一个未选中的警告):

List<TestB> variable = (List<TestB>)(List<?>) collectionOfListA;

问题是,如果您的方法包含TestB,那么它不会返回一个teststa列表,那么如果它是正确键入的呢?然后是这个铸件:

class TestA{};
class TestB extends TestA{};
List<? extends TestA> listA;
List<TestB> listB = (List<TestB>) listA;

可以像您所希望的那样工作(Eclipse会警告您进行未检查的强制转换,这正是您正在做的事情,所以meh)。那么你能用这个来解决你的问题吗?事实上你可以这样做,因为:

List<TestA> badlist = null; // Actually contains TestBs, as specified
List<? extends TestA> talist = badlist;  // Umm, works
List<TextB> tblist = (List<TestB>)talist; // TADA!

这正是你想要的,对吧?或者更确切地说:

List<TestB> tblist = (List<TestB>)(List<? extends TestA>) badlist;

对我来说似乎编纂得很好。

你真的不能*:

示例取自本Java教程

假设有两种类型A和B,使得B扩展了A。 那么下面的代码是正确的:

    B b = new B();
    A a = b;

前面的代码是有效的,因为B是a的子类。 现在,List<A>和List<B>会发生什么?

原来List<B>不是List< a >的子类,因此我们不能写

    List<B> b = new ArrayList<>();
    List<A> a = b; // error, List<B> is not of type List<A>

此外,我们甚至不会写字

    List<B> b = new ArrayList<>();
    List<A> a = (List<A>)b; // error, List<B> is not of type List<A>

*:为了使casting成为可能,我们需要一个共同的父List< a >和List<B>: List<?例如>。以下是有效的:

    List<B> b = new ArrayList<>();
    List<?> t = (List<B>)b;
    List<A> a = (List<A>)t;

但是,您将得到一个警告。你可以通过在你的方法中添加@SuppressWarnings("unchecked")来抑制它。

您可以在Eclipse Collections中使用selectInstances方法。这将涉及创建一个新的集合,但不会像使用强制转换的公认解决方案那样有效。

List<CharSequence> parent =
        Arrays.asList("1","2","3", new StringBuffer("4"));
List<String> strings =
        Lists.adapt(parent).selectInstancesOf(String.class);
Assert.assertEquals(Arrays.asList("1","2","3"), strings);

我在示例中加入StringBuffer是为了说明selectInstances不仅向下转换类型,而且还将过滤集合是否包含混合类型。

注意:我是Eclipse Collections的提交者。