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.
Puede capturar el tipo de comodín en este caso: boolean add (lista Extends JLabel> list) {return addImpl (list); } boolean addImpl (Lista list) {... –
(El código de ejemplo es un poco extraño. Podría volver después de que labels.add devuelve falso. –
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