7

我很难弄清楚这一点。假设我有以下代码:

class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...

public static void main(String[] args) {
    List<Mammal> mammals = getMammals(); // compilation error
}

为什么赋值会导致编译错误?错误类似于:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>

根据我对协方差的理解,该getMammals()方法返回 alist将始终包含Mammal对象,因此它应该是可分配的。我错过了什么?

4

2 回答 2

19

因为getMammals可以返回 a List<Giraffe>,并且如果可以转换为,List<Mammal>那么您就可以向Zebra其中添加 a 。不能允许您将 a 添加Zebra到 的列表中Giraffe,可以吗?

class Zebra extends Mammal { }

List<Giraffe> giraffes = new List<Giraffe>();

List<Mammal> mammals = giraffes; // not allowed

mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes
于 2009-07-26T11:26:02.547 回答
6

好吧,不幸的是,它不是那样工作的。

当您声明 getMammals() 返回List<? extends Mammal>时,这意味着它可以返回List<Mammal>List<Giraffe>不返回List<Animal>

你的 main() 应该是这样的:

public static void main(String[] args) {
    List<? extends Mammal> mammals = getMammals();
    Mammal mammal = mammals.get(0);
}

编辑:关于协方差,这就是通常的意思:

class Animal {
    public Animal getAnimal() {return this;}
}

class Mammal extends Animal {
    public Mammal getAnimal() {return this;}
}

class Giraffe extends Mammal {
    public Giraffe getAnimal() {return this;}
}

如您所见,它允许在覆盖方法时重载方法的返回类型。

于 2009-07-26T11:27:04.103 回答