2012-07-16 22 views
47

¿Cuál es la diferencia entre estas 2 funciones?Java Generics WildCard: <? extiende Número> vs <T extiende Número>

static void gPrint(List<? extends Number> l) { 
    for (Number n : l) { 
     System.out.println(n); 
    } 
} 

static <T extends Number> void gPrintA(List<T> l) { 
    for (Number n : l) { 
     System.out.println(n); 
    } 
} 

veo la misma salida.

+3

Quizás es porque no hay diferencia? –

+0

http://stackoverflow.com/questions/6008241/java-generics-e-and-t-what-is-the-difference – swapy

+0

por qué no podemos definir la clase Nombre pero el nombre de la clase está bien? –

Respuesta

31

No hay diferencia en este caso, porque T nunca se usa de nuevo.

El motivo para declarar un T es que pueda consultarlo de nuevo, vinculando así dos tipos de parámetros, o un tipo de retorno juntos.

+0

De acuerdo! Entonces, ¿hay un caso donde solo '?' hará el trabajo por mí, pero no por 'T'. O lo que sea que se pueda hacer con un comodín se puede hacer usando 'T'? –

+9

Si solo hay un '?', Entonces es equivalente. Si hay más de un '?', Entonces tiene que usar 'T' o'? ', Dependiendo de si necesita que los dos tipos sean iguales, o si desea permitir que sean diferentes. Si tiene un método 'x ( a, b)', puede llamarlo con un Integer y un Long. Si tiene 'T a, T b', ambos deben ser del mismo tipo. – Thilo

+1

Pero aún puedo hacer x (T a, U b). Entonces, ¿cuál es la forma preferida? ¿Se prefiere no usar comodines (siempre que sea posible)? –

33

La diferencia es que no puede consultar T cuando usa un comodín.

Usted no está en este momento, así que no hay "ninguna diferencia", pero aquí es cómo se puede utilizar T para hacer una diferencia:

static <T extends Number> T getElement(List<T> l) { 
    for (T t : l) { 
     if (some condition) 
      return t; 
    } 
    return null; 
} 

Esto devolverá el mismo tipo como lo es pasado . en, por ejemplo estos se tanto de compilación:

Integer x = getElement(integerList); 
Float y = getElement(floatList); 
+0

Entonces, ¿cuándo es realmente necesario el comodín? –

+2

El comodín no es realmente "necesario", pero proporciona menos tipeo cuando en realidad es un tipo de texto no vinculado (no es necesario darle un nombre). El código resultante es equivalente. Esto es similar a la diferencia entre 'int a = 1; devuelve a' versus 'return 1'. O escribiendo '' en vez de '' – Thilo

4

T es un tipo limitado, es decir, cualquier tipo que utiliza, usted tiene que pegarse a ese tipo particular que se extiende Number, por ejemplo, Si pasa un tipo Double a una lista, no puede pasarlo a Short tipo T es del tipo Double y la lista ya está limitada por ese tipo. Por el contrario, si usa ? (wildcard), puede usar "cualquier" tipo que se extienda a Number (agregue Short y Double a esa lista).

0

Cuando utiliza T puede realizar todo tipo de acciones en la lista. Pero cuando lo usas no puedes realizar agregar.

T - igual que la referencia de objeto con pleno acceso
? - dar acceso parcial

static void gPrint(List<? extends Number> l) { 
l.add(1); //Will give error 
for (Number n : l) { 
    System.out.println(n); 
} 

static <T extends Number> void gPrintA(List<T> l) { 
l.add((T)1); //We can add 
for (Number n : l) { 
    System.out.println(n); 
}