2013-01-09 18 views
19

Stavo leggendo di generici e non ho capito la necessità di caratteri jolly non associati e di come si differenzia dal tipo non elaborato. Ho letto this question ma ancora non l'ho capito chiaramente. Nel Java tutorial page for unbound wildcard ho ottenuto qui sotto due punti e non ho capito primo punto:Differenza tra un carattere jolly non associato e un tipo non elaborato

  • Se si sta scrivendo un metodo che può essere implementato usando funzionalità fornita nella classe Object.
  • Quando il codice utilizza metodi nella classe generica che non dipendono dal parametro type. Ad esempio, List.size() o List.clear(). Infatti, Class<?> è così spesso utilizzato perché la maggior parte dei metodi in Class<T> non dipendono da T.

Qualcuno può spiegare la differenza tra jolly non legato e di tipo raw in un linguaggio profano.

In che modo List<?> differisce da List<Object>?

+1

Si noti che il termine "tipo non elaborato" si riferisce a un riferimento non parametrizzato a un tipo generico, ad es. 'Lista' contro' Lista '. Concetti leggermente diversi. – Alex

+4

Giusto per sottolineare che 'Lista ' non è un tipo non elaborato, il suo tipo generico è 'Oggetto'. Un tipo grezzo sarebbe 'List'. – Dmitri

risposta

33

Come List<?> differisce da List<Object>

La differenza principale è che la prima linea compila ma il secondo non lo fa:

List<?> list = new ArrayList<String>(); 
List<Object> list = new ArrayList<String>(); 

Tuttavia, poiché non si sa che cosa il generico tipo di List<?> è, non è possibile utilizzare i suoi metodi parametrizzati:

List<?> list = new ArrayList<String>(); 
list.add("aString"); //does not compile - we don't know it is a List<String> 
list.clear(); //this is fine, does not depend on the generic parameter type 

quanto riguarda la differenza con i tipi di grezzi (non generici), il codice qui sotto compila e funziona bene:

List list = new ArrayList<String>(); 
list.add("aString"); 
list.add(10); 
+0

ottenuto fino ad ora ma come il tipo grezzo è diverso per non associato e perché abbiamo bisogno di carattere jolly unboud? puoi per favore spiegarlo con un buon esempio. –

+0

@Sandy la differenza principale IMO è che l'uso di caratteri jolly non associati (ad esempio in una firma di metodo) segnala una promessa che il metodo in questione è a conoscenza di generici e onorerà il tipo generico di quell'oggetto. Con i tipi non elaborati tutte le scommesse sono disattivate - puoi aggiungere un numero a un elenco di stringhe, come illustrato qui - e mescolare codice generico e grezzo può comportare il rischio di ClassCastExceptions. – Alex

+0

@Sandy Ho illustrato la differenza tra tipi indeterminati (2 ° esempio) e non elaborati (2 ° esempio). Cosa non è chiaro su di loro? – assylias

4

Come List<?> differisce da List<Object>?

List<Object> l1 = new ArrayList(); 
    List<?> l2 = new ArrayList(); 
    l1.add("Object"); 
    //l2.add("Object"); incorrect 
    l2.add(null); 

È possibile aggiungere solo null valore al List<?>

2

Personalmente, ho trovato questo additional link from the Java tutorial on wildcards utile.

Una delle principali differenze che vedo tra List<?> e List è che il primo può sempre e solo essere utile per la lettura da esso è elementi (a meno che non si vuole veramente aggiungere null), il secondo consente (incontrollato) l'aggiunta di oggetti arbitrariamente tipizzati ad esso con effetti collaterali possibilmente inattesi.

0

L'elenco è utile in una firma del metodo per chiamare metodi che non richiedono mai il parametro type, ad esempio la lettura dall'elenco o la rotazione, ad esempio.

void someMethod(List<?> list) { 
    list.clear(); // I will never add anything to the list in here 
} 

Lei non potrà mai aggiungere nulla o altrimenti modificare l'elenco rispetto al tipo che detiene come non si può aggiungere nulla alla lista tranne nulla nei metodi con questa firma e quindi non potrà mai rompere la sicurezza di tipo. L'elenco delle materie prime, d'altra parte, è in grado di fare qualsiasi cosa, il che, come sappiamo, può causare una violazione della sicurezza del tipo.

void someMethod2(List list) { 
list.add(new WeaselFurBrush()); 
} 
List list1 = new ArrayList<String>(); 
someMethod2(list1);// oops