java - 将参数化类转换为参数的子类

标签 java generics casting

有没有办法将某些父类(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 可能包含不属于 BarFoo这不是问题。

似乎这个问题的唯一解决方案是不使用泛型,但是您必须为需要创建列表的每种类型创建此列表的实例,这正是泛型所面临的问题旨在解决。

我们可以强制转换对列表的每个访问,但是程序的当前布局(并且不能轻易更改它)将导致数千次强制转换,就好像我们可以强制转换列表一样,我们只需要一个在一些地方有几个 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/

相关文章:

c++ - 将十六进制字符串转换为结构体

java - PDF 中的文本以不同方式吐出

java - 泛型定义内的原始类型

java - 如何在方法声明中使用类型参数而不是类

C++ 模板对象数组 : Is it UB to cast to a common non-type template parameter?

java - 创建 ListIterator 时会发生什么?

java - 陷入 JOptionPane 循环

java - 如何为 Eclipse 中构建的 Maven 聚合器项目定义 JRE?

java - 用于检索复杂实体的高效 JPQL 查询

可选泛型类型的 Swift 扩展