¿Cuál es la diferencia entre <?> Y <? extiende Object> en Java Generics?

95

He visto el comodín usado antes para referirse a cualquier objeto, pero recientemente vi un uso de:

<? extends Object>

Dado que todos los objetos extienden Object, ¿estos dos usos son sinónimos?

orbe
fuente
3
@Dan Si busca "? Extiende Objeto" en esa pregunta, no encuentra nada. Estoy leyendo las respuestas para ver si puedo inferir algo, pero no creo que sea así. Específicamente, no se trata de genéricos.
orbfish
@Dan - Esa es una pregunta diferente. He visto esta pregunta antes y recuerdo al menos una mención de una diferencia sutil. Déjame ver si puedo encontrarlo ..
Paul Bellora
Tampoco es este si lo encuentra: stackoverflow.com/questions/678822/…
orbfish
1
Aquí vamos: posible duplicado de comodines ilimitados en Java (con una respuesta incorrecta de Kevin Bourrillion nada menos)
Paul Bellora

Respuestas:

104

<?>y <? extends Object>son sinónimos, como era de esperar.

Hay algunos casos con genéricos en los extends Objectque en realidad no es redundante. Por ejemplo, <T extends Object & Foo>hará Tque se vuelva Objecta borrar, mientras que con <T extends Foo>ello se volverá Fooa borrar. (Esto puede ser importante si está intentando mantener la compatibilidad con una API pregenérica que se utilizó Object).

Fuente: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; explica por qué la java.util.Collectionsclase del JDK tiene un método con esta firma:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)
ruakh
fuente
4
No tengo claro cómo se relaciona el ejemplo. (ya que no usa <?> ni <? extiende Objeto>)
orbfish
27
@orbfish: Se relaciona solo en que pensé que lo encontraría interesante, ya que es un ejemplo en el que en extends Objectrealidad es significativo. Si me equivoqué, me disculpo. Con suerte, será de interés para otras personas que se encuentren con su pregunta, al menos.
ruakh
@ruakh: estaba interesado en comodines delimitados en lugar de parámetros de tipo, pero, al menos, respondió.
orbfish
1
Deberías haber dicho eso en tu publicación original entonces. De esa manera, su respuesta podría haber sido más relevante para ti.
liltitus27
19

Aunque <?>se supone que es un atajo para <? extend object>, hay una pequeña diferencia entre los dos. <?>es confiable mientras <? extend object>que no lo es. La razón por la que hicieron esto es para que sea más fácil distinguir los tipos confiables. Cualquier cosa que se parece <? extends something>, <T>, <Integer>son nonreifiable.

Por ejemplo, este código funcionaría

List aList = new ArrayList<>();
boolean instanceTest = aList instanceof List<?>;

pero esto da un error

List aList = new ArrayList<>();
boolean instancetest = aList instanceof List<? extends Object>;

para obtener más información, lea las colecciones y genéricos de Java de Maurice Naftalin

Renzhentaxi Baerde
fuente
¿Cómo puede List <?> Ser confiable si el compilador lo traduce a List <Object> para obtener información sobre cuál es el tipo de? ¿está perdido?
Trismegistos
Lo que creo que <?> Está más diseñado para ser compatible con versiones anteriores de las API heredadas. distinguir con <Objeto> y <? extiende Object> que son código post Java 5.
Dennis C
9

<?>es una abreviatura de <? extends Object>. Puede leer el enlace compartido a continuación para obtener más detalles.


<?>

"?"denota cualquier tipo desconocido. Puede representar cualquier tipo en el código. Utilice este comodín si no está seguro del tipo.

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number
unknownList = new ArrayList<Float>(); //Float is of type Number

Nota: <?> significa cualquier cosa. Por lo tanto, puede aceptar tipos que no se heredan de la Objectclase.

<? extends Object>

<? extends Object>significa que puede pasar un objeto o una subclase que amplía la Objectclase.

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass
numberList = new ArrayList<Integer>(); //Integer extends Number
numberList = new ArrayList<Float>(); // Float extends Number 

ingrese la descripción de la imagen aquí

T - usado para denotar el tipo
E - usado para denotar el elemento
K - teclas
V - valores
N - para números
Ref:

ingrese la descripción de la imagen aquí

roottraveller
fuente
"Por lo que puede aceptar tipos que no se heredan de la clase Object", pero todas las clases Java se heredan o se heredan implícitamente de la Objectclase.
hackjutsu