2010-05-20 8 views

Respuesta

6

Al asignar a una variable (Set<T>) con un tipo genérico no comodín T , el objeto asignado debe tener exactamente T como su tipo genérico (incluidos todos los parámetros de tipo genérico de T, comodín y comodín). En su caso T es Cage<Lion>, que no es del mismo tipo que Cage<? extends Animal>.

Lo que puede hacer, porque Cage<Lion> es asignable a Cage<? extends Animal>, es utilizar el tipo de comodín:

Set<? extends Cage<? extends Animal>> a = new Set<Cage<Lion>>(); 
+0

+1 para la solución real. –

+0

Gracias, para mí, esa fue la parte que faltaba. –

6

Esto está mal, porque si se le permitiera, entonces esto sería legal:

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); 
cc.add(new Cage<Tiger>()); // legal -- Cage<Tiger> is a Cage<? extends Animal> 

Cage<Tiger> está dentro de los límites de la declaración, pero no la definición, por lo que este se estrellaría.

+0

Java ¿Cómo se puede decidir si se aplican contravarianza/covarianza o no? – Simon

+0

Según mi entendimiento, Java trata los genéricos como invariantes (pero, curiosamente, trata los arreglos como covariantes y comprueba los tipos en tiempo de ejecución), pero al escribir métodos con parámetros comodín adecuados (se extiende o super según corresponda) y un poco de fundición y supresión de conversiones no verificadas, puede dar la impresión de lo que sea apropiado en su caso. – pdbartlett

2

que necesita:

Set<? extends List<? extends Number>> cc = new HashSet<ArrayList<Integer>>(); 

Para explicar por qué ... supongo que una copia de seguridad de una versión más simple de su ejemplo:

Number a = new Integer(1); // OK 
Set<Number> b = new HashSet<Integer>(); // not OK 

esto no funciona, ya que permitiría

b.add(new Double(3.0)); 
Cuestiones relacionadas