pensé que tengo una buena comprensión de los genéricos de Java.Java comodín comportamiento extraño cuando la clase es genérico
Este código NO COMPILA y sé por qué.
podemos pasar al método de prueba sólo Lista de Tipo de animal o su tipo súper (como la lista de objetos)
package scjp.examples.generics.wildcards;
import java.util.ArrayList;
import java.util.List;
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}
public class Test {
public void test(List<? super Animal> col) {
col.add(new Animal());
col.add(new Mammal());
col.add(new Dog());
}
public static void main(String[] args) {
List<Animal> animalList = new ArrayList<Animal>();
List<Mammal> mammalList = new ArrayList<Mammal>();
List<Dog> dogList = new ArrayList<Dog>();
new Test().test(animalList);
new Test().test(mammalList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Mammal>)
new Test().test(dogList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Dog>)
Dog dog = dogList.get(0);
}
}
Pero aquí viene la parte extraña (al menos para mí).
si declaramos clase Test como genéricos con sólo añadir <T>, entonces REÚNE! y la arroja java.lang.ClassCastException:
public class Test<T> {
...
}
,
Exception in thread "main" java.lang.ClassCastException: scjp.examples.generics.wildcards.Animal cannot be cast to scjp.examples.generics.wildcards.Dog
Mi pregunta es por qué la adición genérica clase de tipo T < > (que no se utiliza en cualquier lugar) causada clase para compilar y cambiado el comportamiento de comodín?
+1. Debo agregar, que aunque se compila en Eclipse, es seguro que produce un montón de advertencias aterradoras, a las que debes prestar atención. –
En realidad, no solo eclipse, esa advertencia es obligatoria según la especificación: "Una invocación de un método o constructor de un tipo sin procesar genera una advertencia no verificada si la borradura cambia cualquiera de los tipos de cualquiera de los argumentos al método o al constructor". En general, casi todos los códigos que pueden causar * contaminación acumulativa * en tiempo de ejecución son necesarios para generar una advertencia no comprobada en tiempo de compilación. – meriton