Queste cose sono conosciute, in teoria tipo, come varianza, con <? extends T>
essendo una notazione co-variante, e <? super T>
essendo una notazione contra-variante. La spiegazione più semplice è che ?
può essere sostituito da qualsiasi tipo che si estende T
nella notazione co-variante, e ?
può essere sostituito da qualsiasi tipo che T
si estende in quella contro-variante.
L'uso di contromovensione e co è molto più difficile di quanto possa sembrare a prima vista, soprattutto perché la variazione "alterna" a seconda della posizione.
Un semplice esempio potrebbe essere una classe di funzione. Supponiamo che tu abbia una funzione che prende un A
e restituisce un B
. La notazione corretta per questo sarebbe dire che A
è contro-variante e B
co-variante.Per capire meglio come questo è il caso, prendiamo in considerazione un metodo - chiamiamola g
- che riceve questa ipotetica classe funzione, dove f si suppone di ricevere un Arc2D
e restituire una Shape
.
All'interno g
, questo f
è chiamato passando un Arc2D
e il valore restituito viene utilizzato per inizializzare un Area
(che prevede un Shape
).
Ora, supponiamo che lo f
che passi riceve uno qualsiasi Shape
e restituisce un Rectangle2D
. Dal momento che un Arc2D
è una anche una Shape
, poi g
volontà non un errore passando un Arc2D
-f
, e dal momento che un Rectangle2D
è anche un Shape
, allora può essere passato al costruttore Area
s'.
Se si tenta di invertire una delle varianze o di scambiare i tipi previsti e effettivi in quell'esempio, vedrete che fallisce. In questo momento non ho il tempo di scrivere questo codice, e il mio Java è abbastanza arrugginito, ma vedrò cosa posso fare dopo, se nessuno è così gentile da farlo prima.
fonte
2010-02-22 11:42:06
Java efficace è ottimo, ma non ho ancora la 2a edizione (( – Roman
@Roman è possibile scaricare il capitolo su Generics dal collegamento aggiunto :-) –
Grazie, lo leggerò. ci sono altri 'esempi di capitoli' disponibili gratuitamente? – Roman