2009-07-26 73 views
7

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

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()方法返回一个list将始终包含Mammal对象,所以它应该是分配。我错过了什么?

回答

19

因为getMammals可以返回List<Giraffe>,如果这是可转换到List<Mammal>那么你可以一个Zebra添加到它。您不能将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 
6

那么,它不工作就像那样不幸。

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

此致主()应该是这样的:

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;} 
} 

正如你所看到的,它允许超载retu当您重写该方法时的方法类型。

+0

+ 1,但你能解释一下“列表或列表而不是列表”是什么意思?! :p – 2009-07-26 11:30:19

+0

重新格式化以去除令人困惑的'列表或列表但不是列表':-) – 2009-07-26 11:32:14

+0

该泛型被视为html,逃脱 – 2009-07-26 11:32:22