type - java generics bounded wildcards
¿List es el padre común de List<Integer> y List<Number>? (5)
El contexto que necesita comprender no es de Number
Integer
o Number
pero es la List
. Supongamos que usted es el que está creando la clase List
, entonces, ¿cómo crearía la clase, por lo que solo admitirá un tipo específico de clase.
Sí, esa clase List
no usará Object como su tipo, sino que usará un comodín ?
.
Como dice la documentación de WildCards
Entonces, ¿cuál es el supertipo de todo tipo de colecciones? Está escrito
Collection<?>
(Pronunciado "colección de desconocido")
Lo mismo se puede decir de List.
Entonces, ¿cuál es el supertipo de todo tipo de listas? Está escrito
List<?>
(Pronunciado "Lista de desconocido")
Aunque
Integer
es un subtipo deNumber
,List<Integer>
no es un subtipo deList<Number>
y, de hecho, estos dos tipos no están relacionados.El elemento primario común de
List<Number>
yList<Integer>
esList<?>
.
Mi pregunta es sobre la segunda oración. ¿Cómo podemos decir que List<?>
Es el padre común de List<Number>
y List<Integer>
?
?
representa un tipo desconocido, que podría ser cualquier tipo de referencia. Incluso si digo eso ?
Sería Object
aquí, Object
es el padre común de Integer
and Number
NO significa que List<Object>
convierta en un padre común de List<Integer>
y List<Number>
.
El tutorial es sobre comodines. Entonces quieren explicar cuándo y cómo debes usarlos. Cuando lees a continuación está el código de ejemplo:
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number>
Solo puedes hacer esta tarea si ?
es el padre común de Integer
y Number
. Creo que en la relación con comodines y genéricos es posible decir que:
List<?>
Es el padre común deList<Number>
yList<Integer>
porque es necesario ver el contexto del tutorial.
Está mezclando los conceptos de herencia OOP o tipos concretos con uno de los tipos genéricos y las relaciones entre esos genéricos.
Una oración en el tutorial sobre comodines y subtipos lo dice todo:
Para crear una relación entre estas clases ... use un comodín de límite superior
Para las relaciones de tipo genérico ?
es simplemente el más alto limitado de los posibles comodines ? extends <type>
? extends <type>
(comodín de límite superior),? ? super <type>
(comodín de límite inferior) y el type
real (la coincidencia exacta o "comodín de límite superior e inferior").
Los comodines se utilizan para obtener los dos conceptos de genéricos y OOP para que funcionen perfectamente entre sí, pero no es lo mismo. Simplemente ponga: List<?>
Es el padre común de List<Integer>
y List<Number>
porque la relación comodín se especifica como tal con la que cualquier otro comodín crea una relación de subtipo ?
. Esta es más o menos la explicación informal, mira la respuesta de dejvuth para las partes concretas de la especificación.
Estos son los tipos que tienen los métodos en Java con genéricos:
interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}
¡El primer método no usa genéricos en absoluto! El segundo método es la primera vez que vemos una abreviatura importante. El tipo Colección significa:
Collection<? extends Object>
Extender Objeto es uno de los usos más comunes de comodines, por lo que tiene sentido proporcionar un breve formulario para escribirlo.
Podemos probar que List<?>
Es un supertipo de List<Number>
y List<Integer>
.
De JLS 4.10.2 (énfasis mío):
Dada una declaración de tipo genérico C <F1, ..., Fn> (n> 0), los supertipos directos del tipo parametrizado
C<T1,...,Tn>
, donde Ti (1 ≤ i ≤ n) es una tipo, son todos los siguientes:
...
C<S1,...,Sn>
, dondeSi
contieneTi
(1 ≤ i ≤ n) (§4.5.1)
reemplazando C
con List
y n=1
, sabemos que List<?>
es un supertipo directo de List<Number>
y List<Integer>
if ?
contiene Number
y Integer
.
Podemos probar eso ?
contiene Number
y Integer
porque de JLS 4.5.1 :
¿El comodín
? extends Object
? extends Object
es equivalente al comodín ilimitado?
.
y más adelante:
Se dice que un argumento de tipo
T1
contiene otro argumento tipoT2
, escritoT2
<=T1
, si el conjunto de tipos denotados porT2
es probablemente un subconjunto del conjunto de tipos denotados porT1
bajo el cierre reflexivo y transitivo de las siguientes reglas ( donde <: denota subtipificación (§4.10)):
? extends T
? extends T
<=? extends S
? extends S
si T <: S- ...
T
<=? extends T
? extends T
podemos usar las reglas anteriores para demostrar que Number
<= ?
, porque Number
<= ? extends Number
? extends Number
<= ? extends Object
? extends Object
= ?
.