He leído el libro de O'Reilly, en el que llegué a conocer este principio de ponerse manos a la obra .
- Utilice un
extends
comodín cuando solo obtenga valores de una estructura.- Utilice un
super
comodín cuando solo ponga valores en una estructura.- Y no use un comodín cuando ambos quieran obtener y poner desde / hacia una estructura.
Las excepciones son:
No puede poner nada en un tipo declarado con un
extends
comodín excepto el valornull
, que pertenece a cada tipo de referencia.No puede obtener nada de un tipo declarado con un
super
comodín, excepto un valor de tipoObject
, que es un super tipo de cada tipo de referencia.
¿Alguien puede ayudarme a explorar esta regla en profundidad? Si es posible, colóquelos de manera jerárquica.
Respuestas:
Considere un racimo de plátanos. Esto es
Collection<? extends Fruit>
porque es una colección de un tipo particular de fruta, pero no sabes (a partir de esa declaración) de qué tipo de fruta es una colección. Puede obtener un artículo y saber que definitivamente será una fruta, pero no puede agregarle ; es posible que esté tratando de agregar una manzana a un racimo de plátanos, lo que definitivamente estaría mal. Usted puede agregarnull
a ella, como que será un valor válido para cualquier tipo de fruta.Ahora considere un frutero. Esto es un
Collection<? super Banana>
, en el sentido de que es una colección de algún tipo "mayor que"Banana
(por ejemplo,Collection<Fruit>
oCollection<TropicalFruit>
). Definitivamente puede agregar un plátano a esto, pero si saca un artículo del tazón, no sabe lo que obtendrá, es posible que no sea un plátano. Todo lo que sabe con certeza es que será una referencia válida (posiblementenull
)Object
.(En general, para las preguntas sobre genéricos de Java, las Preguntas frecuentes sobre genéricos de Java son un recurso excelente que contiene la respuesta a casi cualquier cosa relacionada con los genéricos que probablemente le arroje).
fuente
Collection<? extends Fruit>
exactamente por esa razón, y tendría que emitir explícitamente el resultado de obtener un elemento, precisamente por esas razones.Collection<? extends Person>
(o más probablemente solo unIterable<? extends Person>
, pero ...). El código que crea esa colección puede necesitar que sea unCollection<Employee>
, pero el código consumidor no lo necesita .