2009-03-29 17 views
7

me topé con una función con este aspecto:<?> vs <T>

public void function(Class<?> clazz) {...} 

Cuáles son las ventajas/desventajas de cambiar el método a:

public <T> void function(Class<T> clazz) {...} 

edición: ¿cuáles son el tiempo de compilación/ejecución diff

Respuesta

7

todd.run está totalmente en lo cierto, pero eso es solo la mitad de la respuesta. También hay casos de uso para elegir <T> sobre <?> (o viceversa) que se aplican cuando no se agrega un parámetro de tipo a la clase que incluye el método. Por ejemplo, considere la diferencia entre

public <E extends JLabel> boolean add(List<E> j) { 
    boolean t = true; 
    for (JLabel b : j) { 
     if (b instanceof JLabel) { 
      t = t && labels.add(b); 
     } 
    } 
    return t; 
} 

y

public boolean add(List<? extends JLabel> j) { 
    boolean t = true; 
    for (JLabel b : j) { 
     if (b instanceof JLabel) { 
      t = t && labels.add(b); 
     } 
    } 
    return t; 
} 

El primer método en realidad no se compile a menos que agregue un parámetro de tipo apropiado a la clase envolvente, mientras que el segundo método se compilará sin importar si la clase adjunta tiene un parámetro de tipo. Si no usa <?>, entonces es localmente responsable de decirle al compilador cómo adquirir el tipo que se completará con la letra utilizada en su lugar. Con frecuencia se encuentra con este problema, ¿necesita usarlo? en lugar de T - al intentar escribir métodos genéricos que usan o necesitan "extender" y "super". Un mejor pero más elaborado tratamiento de este problema está en la página 18 de Gilad Bracha's Generics Tutorial (PDF). También vea this stack overflow question cuya respuesta ilumina estos problemas.

Consulte este enlace de desbordamiento de pila para obtener información acerca de su segunda pregunta: Java generics - type erasure - when and what happens. Si bien no conozco la respuesta a su pregunta sobre la diferencia de tiempo de compilación entre <?> y <T>, estoy bastante seguro de que la respuesta se puede encontrar en this FAQ que Erickson mencionó en esa publicación.

+0

Puede capturar el tipo de comodín en este caso: boolean add (lista list) {return addImpl (list); } boolean addImpl (Lista list) {... –

+0

(El código de ejemplo es un poco extraño. Podría volver después de que labels.add devuelve falso. –

+0

Esta respuesta no tiene sentido y no es correcta. Puse el primer método en una clase sin un parámetro de tipo ('public class test {List labels = new ArrayList (); // agrego el método aquí}') y compila bien. – user102008

2

Básicamente, son equivalentes. Puede usar la primera sintaxis donde no necesita declarar nada del tipo T.

ACTUALIZACIÓN: oh, y T se puede usar para unir tipos: si se utiliza Class<T> en diferentes partes de la función, se referirá a la misma clase, pero no a Class<?>.

+0

Sin embargo, eso no es correcto en situaciones en las que hay múltiples ocurrencias de / en una firma de método. – dmeister

+0

No.En este caso, es un parámetro de tipo específico de método, por lo que no se referirá al mismo tipo que el utilizado en el nivel de clase, incluso si también se lo llama T. –

+0

@saua: nadie está hablando del nivel de clase –

10

Usando "?" es lo mismo que "cualquiera", mientras que "T" significa "un tipo específico". Por lo tanto, comparar estas interfaces:

public interface StrictClass<T> { 
public T doFunction(Class<T> class); 
} 

public interface EasyClass<T> { 
public > doFunction(Class<?> class); 
} 

Ahora, podemos crear clases:

public class MyStrictClass implements StrictClass<String> { 
    public String doFunction(Class<String> stringClass) { 
    //do something here that returns String 
    } 
} 

public class MyEasyClass implements EasyClass<String> { 
    public String doFunction(Class<?> anyClass) { 
    //do something here that returns String 
    } 
} 

Espero que ayude!

+0

"public doFunction" es incorrecto y no debería compilarse. Supongo que querías que fuera una "función pública de T". –

+0

Además, "clase" no se puede usar como nombre de variable porque es una palabra reservada. –