2009-07-26 53 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