2016-02-08 41 views
5

Ho letto alcuni argomenti che trattano alcune domande sui generici, come ad esempio il loro relationship with raw types. Ma mi piacerebbe una spiegazione aggiuntiva su una determinata linea trovata nello Java SE tutorial on unbound generics.Generics Java, caratteri jolly senza restrizioni <?> vs <Object>

Secondo una frase:

L'obiettivo di StampaLista è quello di stampare un elenco di qualsiasi tipo, ma non riesce a raggiungere tale obiettivo - viene stampato solo un elenco di istanze di oggetti; non può stampare Elenco Numero intero >, Elenco <Stringa>, Elenco <Doppio> e così via, poiché non sono sottotipi di Elenco <Oggetto>.

Se capisco bene questa frase; la differenza tra List<?> e List<Object> è che possiamo utilizzare l'argomento tipo List<String> o List<Integer> implementando il primo. Mentre se implementiamo la versione successiva, possiamo usare solo l'argomento type List<Object>. Come se List<?> sia un limite superiore a Object ovvero List<? Object>.

Ma poi la seguente frase mi confonde, nel senso che secondo quanto ho capito in precedenza, List<Object> dovrebbe contenere solo istanze della classe Object e non qualcos'altro.

È importante notare che List<Object> e List<?> non corrispondono. È possibile inserire un oggetto o qualsiasi sottotipo di oggetto in un List<Object>. Ma puoi inserire solo null in un List<?>.

+2

Devo andare con "non chiaro cosa stai chiedendo" qui. – Mena

+0

Vuole "una spiegazione aggiuntiva". – ctst

+0

Non sai da dove ricevi le informazioni, ma entrambe le frasi di esempio fornite sono sbagliate. – jervine10

risposta

9

Ci sono due problemi separati qui. Un List<Object> può infatti prendere qualsiasi oggetto come dici tu. Un List<Number> può richiedere almenoNumber oggetti o, naturalmente, qualsiasi sottoclasse, come Integer.

Tuttavia, un metodo come questo:

public void print(List<Number> list); 

sarà effettivamente solo prendere un List che è esattamente List<Number>. Non prenderà alcuna lista che è dichiarata List<Integer>.

Quindi la differenza è List<?> prenderemo alcun elenco con qualunque dichiarazione, ma List<Object> sarà solo prendere qualcosa che era dichiarato come List<Object>, nient'altro.

L'ultima citazione afferma semplicemente che List<?> è un elenco per il quale non si sa letteralmente di che tipo si tratti. Per questo motivo, non è possibile aggiungere nulla ad eccezione di null.

+0

E che ne dite di 'Elenco '? – biziclop

+2

'Elenco 'prenderebbe qualsiasi lista * dichiarata * almeno al numero, quindi ci vorrebbe' Elenco 'e' Lista ' –

+0

Ciò potrebbe essere degno di menzione, dato che' Elenco 'è in qualche modo analogo a' List '. Quindi la differenza tra 'Lista ' e 'Lista ' è come la differenza tra 'Lista ' e 'Lista '. – biziclop

7

La frase che ti confonde sta cercando di avvisarti che, mentre List<?> è il super-tipo di tutti gli elenchi generici, non è possibile aggiungere nulla a una raccolta List<?>.

Supponiamo si è tentato il seguente codice:

private static void addObjectToList1(final List<?> aList, final Object o) { 
    aList.add(o); 
} 

private static void addObjectToList2(final List<Object> aList, final Object o) { 
    aList.add(o); 
} 

private static <T> void addObjectToList3(final List<T> aList, final T o) { 
    aList.add(o); 
} 


public static void main(String[] args) { 
    List<String> testList = new ArrayList<String>(); 
    String s = "Add me!"; 
    addObjectToList1(testList, s); 
    addObjectToList2(testList, s); 
    addObjectToList3(testList, s); 
} 

addObjectToList1 non si compila, perché non si può aggiungere nulla, tranne null ad un List<?>. (Questo è quello che la frase sta cercando di dirti.)

addObjectToList2 compila, ma la chiamata ad essa in main() non si compila, perché List<Object> non è un super tipo di List<String>.

addObjectToList3 sia compila che la chiamata funziona. Questo è il modo di aggiungere elementi a un elenco generico.