我的问题是关于Java 7中的泛型的。假设我们有这样的类层次结构:

interface Animal {}
class Lion implements Animal {}
class Butterfly implements Animal {}

就像Java Generics Tutorial

我们还有一个类
class Cage<T> {
    private List<T> arr = new ArrayList<>();
    public void add(T t) {
        arr.add(t);
    }
    public T get() {
        return arr.get(0);
    }
}

这是使用该类的代码:
public static void main(String[] args) {
        Cage<? extends Animal> cage = new Cage<>();
        Animal a = cage.get(); //OK
        cage.add(new Lion()); //Compile-time error
        cage.add(new Butterfly()); //Compile-time error
    }

问题1:

我已经阅读了有关这些问题的here,但是就像Cage<?>一样。但是我告诉编译器<? extends Animal>,所以T中的Cage<T>类型将是Animal类型的任何子类型。那么为什么它仍然给出编译时错误?

问题2:

如果我指定Cage<? super Animal> cage = ...而不是Cage<? extends Animal> cage = ...,那么一切正常,编译器不会说不好。为什么在这种情况下它可以正常工作,而在上面的示例中却失败了?

最佳答案

笼子必须能够容纳两种动物。 “super”表示-表示笼子必须能够容纳所有类型的动物-也许还有其他一些东西,因为? super Animal可能是Animal的父类(super class)。 “扩展”表示它可以容纳某些动物-例如,也许只是狮子,例如:

Cage<? extends Animal> cage = new Cage<Lion>();

这是一个有效的声明,但是很明显,狮子笼不会抱蝴蝶,所以
cage.add(new Butterfly());

不会编译。该声明
cage.add(new Lion());

也不会编译,因为Java在这里查看的是笼子的声明-Cage<? extends Animal>-而不是现在分配给它的对象(Cage<Lion>)。

我知道的对泛型的最佳描述是在O'Reilly's Java in a Nutshell中。本章是免费的在线版本-part 1part 2

关于java - 泛型中的通配符: "? super T" works while "? extends T" does not?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7541849/

10-12 05:08