例如,假设你有两个类:

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

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


当前回答

不过我认为你选错方向了……如果该方法返回一个TestA对象列表,那么将它们强制转换到TestB确实是不安全的。

基本上,您是在要求编译器允许您在不支持TestA类型的TestB上执行操作。

其他回答

由于类型擦除,这是可能的。你会发现

List<TestA> x = new ArrayList<TestA>();
List<TestB> y = new ArrayList<TestB>();
x.getClass().equals(y.getClass()); // true

在内部,两个列表的类型都是List<Object>。出于这个原因,你不能将一个转换为另一个——没有什么可以转换的。

问题是,如果您的方法包含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;

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

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

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

泛型的强制转换是不可能的,但是如果你以另一种方式定义列表,则可以将TestB存储在其中:

List<? extends TestA> myList = new ArrayList<TestA>();

在使用列表中的对象时,仍然需要进行类型检查。

简单的答案

你不能直接类型转换。

解决方案

 public <T> List<T> getSubItemList(List<IAdapterImage> superList, Class<T> clazz) {
        return superList.stream()
                .map(item -> clazz.isInstance(item) ? clazz.cast(item) : null)
                .collect(Collectors.toList());
    }

使用

private final List<IAdapterImage> myList = new ArrayList<>();

List<SubType> subTypeList = getSubItemList(myList,SubType.class);

所以这是一个简单的工作,我用来转换我的列表与超级类型到列表与子类型。我们使用的是java 8中引入的流api,在我们的超列表上使用map,我们只是检查传递的参数是否是我们的超类型的实例,返回项目。最后,我们收集成一个新的列表。当然,我们需要把result放到一个新的列表中。