2009-07-26 17 views
7

Sto attraversando un periodo difficile cercando di capirlo. Supponi di avere il seguente codice:covarianza 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 
} 

Perché l'assegnazione genera un errore di compilazione? L'errore è qualcosa di simile:

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

Secondo la mia comprensione della covarianza, il metodo restituisce un getMammals()list che conterrà sempre Mammal oggetti in modo che dovrebbe essere assegnabili. Cosa mi manca?

risposta

19

Perché getMammals potrebbe tornare un List<Giraffe>, e se questo era convertibile a List<Mammal> allora si sarebbe in grado di aggiungere un Zebra ad esso. Non ti è permesso aggiungere un numero Zebra a un elenco di Giraffe, puoi?

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

Beh, purtroppo non funziona così.

Quando si dichiara getMammals() per restituire List<? extends Mammal> che significa che può tornare List<Mammal> o List<Giraffe> ma non List<Animal>

Distinti main() dovrebbe essere simile a questo:

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

EDIT: Per quanto riguarda la covarianza, che è cosa si intende di solito:

Come si può vedere, consente di sovraccaricare la retu rn tipo di metodi quando si esegue l'override del metodo.

+0

+ 1, ma potresti spiegare cosa significa "Elenco o elenco ma non elenco" ?! : p –

+0

Riformattato per rimuovere "Elenco o Elenco ma non elenco" di confusione :-) –

+0

I generici venivano trattati come html, escape –