wildcards type objects node generic example data bounded java generics inheritance polymorphism

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")

De este tutorial de Oracle ,

Aunque Integer es un subtipo de Number , List<Integer> no es un subtipo de List<Number> y, de hecho, estos dos tipos no están relacionados.

El elemento primario común de List<Number> y List<Integer> es List<?> .

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 de List<Number> y List<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> , donde Si contiene Ti (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 tipo T2 , escrito T2 <= T1 , si el conjunto de tipos denotados por T2 es probablemente un subconjunto del conjunto de tipos denotados por T1 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 = ? .