2012-10-06 21 views
6

Stavo rivedendo il codice di qualcun altro l'altro giorno e mi sono imbattuto in una riga che sollevava qualche preoccupazione. Per semplificare, diciamo che ho una Classe A generica e una Classe B. astratta. È consentita la seguente istanziazione e, in tal caso, perché?Creazione di caratteri jolly generici

Object obj = new A<? extends B>(); 

personalmente ho mai visto un esemplificazione come il precedente, anche se una dichiarazione come

A<? extends B> obj = null; 

sarebbe certamente tenere. Ho sempre usato il carattere jolly nei generici per dichiarare i parametri del metodo, quindi potrei non avere l'esperienza.

+0

quale versione di java usi? –

+0

correlati se non duplicati: http://stackoverflow.com/questions/9147129/creating-new-generic-object-with-wildcard e http://stackoverflow.com/questions/12200136/cannot-instantiate-type-in- generici? lq = 1 –

risposta

3

In realtà new A<? extends B>() non viene compilato. È stato costantemente illegale da Java 5.

Ma immagino che il tuo esempio originale fosse qualcosa come new A<X<? extends B>>(). Quest'ultimo è legale nelle versioni recenti di Java.

L'idea è, quando si crea un'istanza di un oggetto, il valore per i parametri di tipo può essere qualsiasi tipo non jolly. ? extends B è un tipo jolly, quindi non è consentito. Ma X<? extends B> non è un tipo jolly, anche se è ha un tipo jolly come componente un. Quindi puoi dire legalmente chiamare new A<X<? extends B>>().

Le regole hanno senso se ci pensi in questo modo. In definitiva si tratta di un sottoprodotto della regola più fondamentale che un tipo jolly come ? extends B non può essere il dichiarato di tipo di un campo o variabile. Se A è definito come

class A<T> { 
    T value; 
} 

poi l'ipotetica new A<? extends B>().value sarebbe un campo dichiarata di tipo? extends B. Dal momento che ciò è illegale, lo è anche l'istanziazione. Ma new A<X<? extends B>>() non ha questo problema.

+0

Risposta abbastanza buona ma non credo che il ragionamento nella seconda parte abbia molto senso. Se una variabile 'a' viene digitata come' A 'ciò non significa che' a.value' è * dichiarato * come '? estende B' - 'value' è dichiarato come' T' dove 'A' dichiara' T'. 'a.value' fa * Valuta * a'? estende B'. Vedi la mia risposta a una domanda simile [qui] (http://stackoverflow.com/a/9147768/697449). –

+0

@PaulBellora Ammesso, non ero molto chiaro nella seconda parte. Quello che intendevo dire era che c'è una differenza tra il tipo putativo di _expression_ 'a.value' e il tipo dichiarato di _variable_' a.value'. Si noti che una variabile è sia un valore r sia un valore l, quindi se si è autorizzati a creare una variabile/campo con un carattere jolly '? estende T' (o '? super T') sarebbe una variabile intrinsecamente handicappata. Non saresti in grado di usarlo come valore r, (valore-l, rispettivamente). Ora, è tollerabile per un riferimento ordinario 'a', ma mai per' questo'. – Saintali

Problemi correlati