2010-11-22 20 views
15

Tengo un método cuyo argumento debe ser "una Lista de cualquier cosa". El método no modificará el contenido de la lista. ¿Es más correcto definir este método comoLista <?> o Lista <Object>

void foo(List<?> list) { 
} 

o

void foo(List<Object> list) { 
} 

y qué es exactamente la diferencia?

Respuesta

12

Respuesta corta, usando List<?> le permitirá aceptar algo así como List<String> mientras usa List<Object> no lo hará.

Esto se discute en la ruta oficial de genéricos, here y here.

[...] aquí es un ingenuo intento de escribir usando genéricos (y la nueva sintaxis para circular):

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

El problema es que esta nueva versión es mucho menos útil que la el viejo. Mientras que el código anterior podía llamarse con cualquier tipo de colección como parámetro, el nuevo código solo toma Collection<Object>, que, como acabamos de demostrar, ¡no es un supertipo de todo tipo de colecciones!
Entonces, ¿cuál es el supertipo de todo tipo de colecciones? Está escrito Collection<?> (se pronuncia "colección de desconocido"), es decir, una colección cuyo tipo de elemento coincide con cualquier cosa. Se llama comodín por razones obvias.Podemos escribir:

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

y ahora, podemos llamarlo con cualquier tipo de colección.

0

Si no desea modificar la lista, entonces es más adecuado que List<?>.

De esta manera puede pasar e. gramo. List<String> y List<BigInteger> a su método.

0

Necesita void foo(List<?> list), de lo contrario no podrá, por ejemplo, pasar un List<String>.

Si usa void foo(List<Object> list), solo puede pasar List<Object>.

Esto es porque, en Java, los genéricos no son covariant: List<String> no es un subtipo de List<Object>.

1

Los dos son bastante diferentes

void foo(List<?> list) 

significa que espera una lista de algo, pero no se ha especificado lo que es

void foo(List<Object> list) 

dice que espera que la lista aprobada es una lista de objetos , por lo que si intenta pasar una Lista, no se aceptará (a diferencia de la primera declaración)

Un error común es suponer que List<String> es un subtipo para hablar de List<Object>, este no es el caso, aunque String es un suptype de Object.

+0

"sólo que la lista no es un tipo de crudo", no, no puede aceptar un tipo de prima, así ... – aioobe

+0

eso es cierto, fijo – hhafez

0

El List<Object> ha parametrizado tipo Object lo cual significa básicamente que se puede añadir todos objetos en la lista. Sin embargo, List<?> significa que es una lista de incógnitas. Mientras usted no va a añadir nada a la lista, que es esencialmente el mismo que List<Object> pero tendrá que preocuparse con las circunstancias de la siguiente manera:

List<?> unknownList = new ArrayList<String>(); 
unknownList.add(new Object()); //Compilation error. 

El ? (en este caso) significa que puede solo agrega valores de String o es subtipo de String.

Si solo va a iterar por la lista y recuperar valores, List<?> y List<Object> es esencialmente el mismo.

Más información here.

+0

No se puede agregar cualquier cosa menos NULL a una lista TigerBear

+0

Si está usando una lista de incógnitas, sí. –

0

Sección 3 y 4 de este tutorial deben responder a su pregunta:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Citando del tutorial:

En general, si foo es un subtipo (subclase o subinterfaz) de Barra, y G es una declaración de tipo genérico, no es el caso que G <Foo> es un subtipo de G <Barra> ....

... Colección <Objeto>, que, como acabamos de demostrar, ¡no es un supertipo de todo tipo de colecciones! Entonces, ¿cuál es el supertipo de todo tipo de colecciones? Está escrito Colección <? > (pronunciado "colección de desconocido"), es decir, una colección cuyo tipo de elemento coincide con cualquier cosa.

Sin embargo, bajo la estricta supuesto de que el método foo dejará sin modificar la colección, no debería haber ninguna diferencia en la aplicación.

+0

lol, @aioobe publicó el mismo enlace y me ganó. – CubaLibre

Cuestiones relacionadas