2009-09-25 13 views
8

Disculpe si el título parece confuso, pero hay algunos ejemplos en orden.¿Por qué no se puede asignar un tipo genérico que contiene un tipo genérico a una clase genérica de tipo comodín?

Digamos que tengo alguna clase de Java con un parámetro de tipo genérico:

public class GenericClass<T> { 
} 

que puede crear una variable de tipo para almacenar un objeto, con el parámetro genérico establecido en, digamos un String. Java también me permite asignar dicha variable a otra, pero con el parámetro genérico establecido en el tipo de comodín <?>:

GenericClass<String> stringy = ... 
GenericClass<?> generic = stringy; // OK 

Sin embargo, cuando se trabaja con una clase con un parámetro genérico, si se establece el tipo de ese parámetro ser genérico, después no se puede asignar un objeto de esa clase a un tipo de forma idéntica mecanografiado/genericized donde el último parámetro (interior/anidada) es del tipo comodín <?>:

GenericClass<GenericClass<String>> stringy = ... 
GenericClass<GenericClass<?>> generic = stringy; // Compile Error 

// And just in case that is confusing, a more 
// realistic example involving Collections: 
List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; // Compile Error 

el error de compilación específica es :

Type mismatch: cannot convert from List<GenericClass<String>> to List<GenericClass<?>> 

Intuitivamente, creo que la tarea en cuestión no debería ser un problema. Entonces, ¿por qué esta tarea es un problema?

+0

Duplicado de http://stackoverflow.com/questions/1341093/nested-generics-with-wildcards – Dirk

Respuesta

8

El problema que su orientación se denomina Covariance.

List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; 
generic.add(new GenericClass<Integer>()); 

Si esto no fue un error de compilación, entonces la última línea de código sería posible.

Se podía moverse el error al hacer esto:

List<? extends GenericClass<?>> generic = stringy; 

pero no se puede utilizar add también porque no se sabe muy bien lo que es ? extends GenericClass<?> (Covarianza una vez más). En este caso, solo puede enumerar a través de la Lista y esperar GenericClass<?>.

4

Técnicamente, eso es porque List<GenericClass<String>> no es un subtipo de List<GenericClass<?>>. Con el fin de hacer que funcione, usted podría hacer algo como

List<? extends GenericClass<?>> generic = stringy 

que debería funciona como se esperaba (aunque es bastante feo ...).

Véase, por ejemplo, this SO question para más detalles

Cuestiones relacionadas