2009-05-27 14 views
36

Ho una domanda Java sui generici. Ho dichiarato un elenco generico:Elenco <? estende MyType>

List<? extends MyType> listOfMyType; 

Poi in qualche modo cerco di istanziare e aggiungere elementi a quella lista:

listOfMyType = new ArrayList<MyType>(); 
listOfMyType.add(myTypeInstance); 

Dove myTypeInstance è solo un oggetto di tipo MyType; non verrà compilato. Dice:

Il metodo add (? Capture # 3 di estende MyType) nel tipo List < cattura # 3 di ? si estende MyType> non è applicabile per gli argomenti (MyType)

Qualche idea?

risposta

29

Non si può fare un "put" con estensioni. Guarda su Generics - Get and Put rule.

+9

Come dice Josh Bloch: "Ricordati PECS: Produttore estende, Super consumatori." Poiché listOfMyType è un consumatore (si sta aggiungendo ad esso), 'super' è valido e' extends' non lo è. –

+0

I collegamenti sono ora interrotti. –

+0

Punto di pedanteria: puoi 'mettere'' null' "con extends".Inoltre puoi catturare il tipo e "mettere" i riferimenti che hai "ottenuto" in precedenza. –

4

Non dovrebbe essere necessario utilizzare la sintassi di cattura jolly nel tuo caso, limitandosi a dichiarare

List<MyType> listOfMytype; 

dovrebbe essere sufficiente. Se vuoi sapere esattamente perché, lo Java Generics Tutorial ha più di quello che vorresti sapere sulla follia esoterica di Java Generics. Page 20 affronta il tuo caso specifico.

Per quanto riguarda il motivo per cui aggiungere con la cattura jolly non funziona, è perché il compilatore non può determinare esattamente quale sottoclasse di MyType l'elenco sarà in ogni caso, quindi il compilatore emette un errore.

22

considerare:

class MySubType extends MyType { 
} 

List<MySubType> subtypeList = new ArrayList<MySubType>(); 
List<? extends MyType> list = subtypeList; 
list.add(new MyType()); 
MySubType sub = subtypeList.get(0); 

sub ora contiene un MyType che è molto sbagliato.

+0

Non dovrebbe il "list.get (0);" in realtà essere "subtypeList.get (0);" ? – Zds

+0

@ Zds Sì, corretto. Grazie. –

2

C'è un filo simile qui: How can elements be added to a wildcard generic collection?

Per avere un'idea di come generici lavori controllare questo esempio:

List<SubFoo> sfoo = new ArrayList<SubFoo>(); 
    List<Foo> foo; 
    List<? extends Foo> tmp; 

    tmp = sfoo; 
    foo = (List<Foo>) tmp; 

Il fatto è, che non è stato progettato per locali/membro variabili, ma per le firme delle funzioni, ecco perché è così arretrato.

2

non so se questo sarà davvero aiutare, ma questo è qualcosa che ho dovuto usare durante la chiamata di un metodo generico di Spring Framework e di voler tornare anche un elenco generico:

public <T> List<T> findAll(String tableName,Class<?> table) { 
    String sql = "SELECT * FROM "+ tableName ; 
    List<?> entities = getSimpleJdbcTemplate().query(sql, 
      ParameterizedBeanPropertyRowMapper.newInstance(table)); 
      return (List<T>) entities; 
} 

sembra che la necessità di parametrizzazione tu per usare il? accedere all'elenco per ricevere i risultati e quindi eseguire il cast dell'elenco sul tipo di reso previsto.

Iam ancora abbagliato da farmaci generici ...

Problemi correlati