2011-04-28 25 views
7

Estoy leyendo el tutorial de Java sobre comodines en genéricos. En el siguiente código:Cómo funcionan los comodines en Java

void printCollection(Collection<Object> c) { 
    for (Object e : c) { 
     System.out.println(e); 
    } 
} 

hace esto significa la colección c toma tipo object como sus elementos, y no podemos llamar c.add("apple"), porque "manzana" es una cadena y el bucle for toma ningún object elementos de la colección c?

Pero no entiendo el siguiente código,

void printCollection(Collection<?> c) { 
    for (Object e : c) { 
     System.out.println(e); 
    } 
} 

Este código utiliza comodines, que significa "una colección cuyo tipo de elemento concuerda con algo." ¿Esto significa que podemos agregarle cualquier tipo de objeto, como c.add("string");, c.add(1); y c.add(new apple());? y el bucle for toma cualquier objeto e de la colección c, si c no es un tipo object, decimos que los elementos c son Entero. ¿Funciona este código? ¿Esto significa que debería ser lanzado?

Respuesta

5

Lo tienes casi exactamente al revés.

Un Collection<Object> puede contener Object y subclases de la misma, y ​​puesto que todo (incluyendo String) es una subclase de Object, se puede añadir nada a tal colección. Sin embargo, no puede hacer suposiciones sobre su contenido, excepto que son Object s.

Por otro lado, un Collection<?> sólo contiene las instancias de un determinado desconocida tipo (y sus subclases), pero ya que no sabe cuales tipo que sea, no se puede agregar nada (excepto null) a tal colección, ni hacer suposiciones sobre sus conents (excepto que son Object s, porque todo es).

0

En Angelika Langer's Java Generics FAQ, pregunta "¿Cuál es la diferencia entre el tipo de carácter comodín ilimitado y el tipo sin formato?" (link) verá que Collection<?> y Collection<Object> son casi equivalentes.

+1

No son equivalentes cuando se trata de agregar cosas a ellos. –

0

En el caso de la segunda declaración, el "?" comodín significa que el genérico no está definido. El resultado es que el tipo está vinculado a "Objeto" porque este es el límite predeterminado para ninguna declaración.

De hecho, incluso "Entero" es una subclase de Objeto. Si quiere decir "int", tiene razón, es un primitivo y no un derivado de Object, pero no puede ponerlo en una Collection, ya que una Collection solo permite derivados de Object.

Y a la pregunta si los elementos puestos en la colección deben ser casted. No, eso no es necesario ya que son claras clases derivadas de Object. El compilador no necesita ninguna información de conversión explícita, resuelve la definición correcta de clase automáticamente.