2011-11-08 24 views
67

he visto el comodín utilizado antes para referirse a cualquier objeto - pero recientemente vi un uso de:¿Cuál es la diferencia entre <?> y <? extiende Object> en Java Generics?

<? extends Object> 

Dado que todos los objetos de objeto extendido, estas son las dos usos sinónimo?

+2

Es lo mismo. Consulte http://stackoverflow.com/questions/2274720/java-extends-object-question – Dan

+3

@Dan Si busca "? Extends Object" en esa pregunta, no encuentra nada. Estoy leyendo las respuestas para ver si puedo inferir algo, pero no creo que sea esto. Específicamente, no está hablando de genéricos. – orbfish

+0

@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 ... –

Respuesta

77

<?> y <? extends Object> son, como era de esperar, pero hay algunos casos con genéricos donde extends Object no es realmente redundante. Por ejemplo, <T extends Object & Foo> causará que T se convierta en Object bajo borrado, mientras que con <T extends Foo> se convertirá en bajo borrado. (Esto puede importa si usted está tratando de mantener la compatibilidad con un API de pre-genéricos que utiliza Object.)

(Fuente: http://download.oracle.com/javase/tutorial/extra/generics/convert.html, sino que explica por qué la clase del JDK java.util.Collections tiene un método con esta firma:

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 

.)

+4

No estoy claro cómo se relaciona el ejemplo? (ya que no usa ni ni ) – orbfish

+5

+1 Muy interesante independientemente. –

+22

@orbfish: Se refiere solo a que pensé que lo encontrarías interesante, ya que es un ejemplo donde 'extends Object' en realidad * es * significativo. Si estaba equivocado, me disculpo. Con suerte, será de interés para otras personas al hacer su pregunta, al menos. – ruakh

17

Aunque <?> se supone que es un acceso directo para <? extend object>, hay una pequeña diferencia entre los dos. <?> es modificable, mientras que <? extend object> no lo es. La razón por la que hicieron esto es para que sea más fácil distinguir el tipo que se puede volver a calcular. Todo lo que se parece a <? extends something>, <T>, <Integer> no se puede verificar.

Por ejemplo, el 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 más información leer los genéricos y colecciones de Java por Maurice Naftalin

+0

¿Cómo puede la lista ser reificable si el compilador lo traduce a la lista para que la información acerca de qué es el tipo? ¿está perdido? – Trismegistos

+0

Lo que creo está más diseñado para compatibilidad con versiones anteriores de API heredadas. para distinguir con y que son post código Java 5. –

2

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


<?> 

"?" denota cualquier tipo desconocido, puede representar cualquier tipo de código para al. Utilice este comodín si no está seguro acerca de Type.

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

Nota:<?> significa anythings. Por lo tanto, puede aceptar el tipo que no se hereda de la clase Object.

<? extends Object> 

<? extends Object> significa que puede pasar un objeto o una sub-clase que se extiende Object clase.

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

enter image description here

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

enter image description here

Cuestiones relacionadas