2013-04-02 18 views
5

Questo codice:<? extends > Java

List<? extends Reader> weirdList; 
weirdList.add(new BufferedReader(null)); 

ha un errore di compilazione di

il metodo Add nella lista tipo non è applicabile per la (cattura # 1-of estende Reader?) argomenti (BufferedReader)

Perché? BufferedReader estende il lettore, quindi perché non è una "corrispondenza"?

+2

possibile duplicato di [Java Generics WildCard Domanda: Elenco ] (http://stackoverflow.com/questions/5495383/java-generics-wildcard-question-list-extends-a) – yshavit

+0

(FWIW, cosa vuoi qui è 'Lista ', non 'Lista '.) –

risposta

3

Per la variabile hai dato:

List<? extends Reader> weirdList; 

Tutte le seguenti assegnazioni sono validi:

weirdList = new ArrayList<Reader>(); 
weirdList = new ArrayList<FileReader>(); 
weirdList = new ArrayList<BufferedReader>(); 
weirdList = new ArrayList<InputStreamReader>(); 

Speriamo che questo spiega il vostro errore di compilazione. Quello che stai cercando ha senso se weirdList contiene un valore di tipo ArrayList<BufferedReader>, ma non ha senso per un valore di tipo ArrayList<FileReader>. Poiché una variabile di tipo List<? extends Reader> può contenere un valore di uno dei due tipi (e anche di più!), Java chiama un errore.

I generici in Java sono difficili da capire. Puoi pensare che il tipo List<? extends Reader> sia utile soprattutto per i tipi di assegnamento o parametro nei metodi, in modo che possano accettare un'ampia varietà di tipi. Per "uso regolare", probabilmente stai meglio con un generico "nudo" come List<Reader> o anche List<BufferedReader>.

6

Quando il compilatore vede <? extends Reader>, allora si assume che potrebbe essere qualsiasi tipo che sia o estende Reader. Potrebbe essere qualcosa che è incompatibile con BufferedReader, ad esempio StringReader. Quindi se il tipo generico nella definizione della classe viene visualizzato nel parametro di un metodo come add e il tipo dell'istanza ha qualcosa come <? extends Something>, il compilatore deve disabilitarlo per motivi di sicurezza del tipo. In questo esempio, potrebbe essere List<StringReader>, quindi non si dovrebbe essere in grado di aggiungere uno BufferedReader qui.

6

List<? extends Reader> weirdList può contenere riferimento a qualsiasi tipo di List che memorizza qualsiasi tipo di Reader. Quindi è possibile che

List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>(); 
List<? extends Reader> weirdList2 = new ArrayList<FileReader>(); 

Se Java permetterebbe di aggiungere BufferedReader a weirdList1 avrebbe anche che consente di aggiungere BufferedReader a weirdList2 (tipo di riferimento è lo stesso) che non è supponiamo che accada poiché weirdList2 dovrebbe memorizzare solo FileReader s.

Problemi correlati