2009-09-25 3 views
8

Извините, если заголовок кажется запутанным, но некоторые примеры в порядке.Почему не может быть присвоен общий тип, содержащий тип Generic, для типичного типизированного класса подстановочного типа

Скажем, у меня есть класс Java с параметром универсального типа:

public class GenericClass<T> { 
} 

Я могу создать переменную набранный для хранения объекта, с общим набором параметров, чтобы, скажем, String. Java также позволит мне присвоить эту переменную в другой переменной, но с общим набором параметров к типу подстановочные <?>:

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

Однако, при работе с классом с родовым параметром, если вы установите тип этого параметра чтобы быть универсальными, вы не можете назначить объект этого класса тождественна набранным/типа обобщенный, где последний (внутренний/вложенным) параметра типа подстановочных <?>:

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 

Специфическая ошибка компиляции является :

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

Интуитивно я думаю, что данное задание не должно быть проблемой. Итак, почему это задание является проблемой?

+0

Дубликат http://stackoverflow.com/questions/1341093/nested-generics-with-wildcards – Dirk

ответ

8

Проблемы вашей облицовочный выражена Covariance.

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

Если это не ошибка компиляции, возможно, последняя строка кода будет возможна.

Вы можете обойти эту ошибку, делая это:

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

, но вы не можете использовать add также потому, что вы на самом деле не знаете, что ? extends GenericClass<?> есть (ковариации еще раз). В этом случае вы можете перечислить только список и ожидать GenericClass<?>.

4

Технически, это потому, что List<GenericClass<String>> не является подтипом List<GenericClass<?>>. Для того, чтобы заставить его работать, вы могли бы сделать что-то вроде

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

, который должен работать, как ожидалось (хотя это довольно некрасиво ...).

См, например, this SO question для получения более подробной информации

Смежные вопросы