java - Java中的泛型类型——高级多态性

标签 java oop generics object polymorphism

我有 3 个简单的类,如下所示:

public class ElementA {}
public class ElementB extends ElementA {}
public class ElementC extends ElementB {}

然后,例如,如果我想创建仅采用 ElementA 类的子类的通用列表,我可以将其声明为:

List<? super ElementA> list = new ArrayList<>();

然后按如下方式使用它:

list.add(new ElementA());
list.add(new ElementB());
list.add(new ElementC());

这很好,可以编译而不会出现错误。但如果我想存储除 ElementC 或 ElementB 或 ElementA 以外的任何内容,我就会感到困惑。我声明该列表如下:

List<? extends ElementC> list = new ArrayList<>();

我根本无法使用它,因为它只能存储空值。当我将 List 声明为(请注意,我使用的是“在家庭中间”的类)时,也会发生同样的事情:

List<? extends ElementB>

为什么会这样?

最佳答案

问题在于 ? 的值在运行时是未知的。您必须替换具体的类/接口(interface)才能执行您想要的操作。

如果你这样做:

List<ElementA> list = new ArrayList<ElementA>();

ElementB开始你就很好了 ElementA同时。相同代表 ElementC

List<? extends ElementA>例如,如果您在类中声明它,并且在子类中您可以替换具体的东西作为类型参数,那么这是有意义的。笨拙的例子:

public class SomeClass<T> {
    private List<? extends T> list;

    public void setList(List<? extends T> list) {
        this.list = list;
    }
}

public class SomeConcreteClass extends SomeClass<Integer> {

    public void doSomething() {
        List<Integer> list = new ArrayList<Integer>();
        setList(list);
    }
}

关于java - Java中的泛型类型——高级多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19184862/

相关文章:

java - 如何在java中更新xml文件

java - 为什么使用静态 block 而不是直接初始化实例变量?

java - 将周期性任务与另一个线程同步

java - 寻找快乐的数字

java - 子类实例变量如何与父类实例联系

generics - Newtype 作为 Rust 中的泛型参数?

c# - 绑定(bind)到值类型的通用类型参数 - 使它们可以为空

javascript - 使用 getter/setter 获取动态对象属性

php - PHP中一个类可以实现多少个接口(interface)?

跨依赖 Java 类型的 Java 通用参数