Обобщения являются инвариантами.
Object o = "someString"; // FINE!
Class<Object> klazz = String.class; // DOESN'T COMPILE!
// cannot convert from Class<String> to Class<Object>
В зависимости от того, что вам нужно, вы можете использовать подстановочные знаки.
Class<? extends Number> klazz = Integer.class; // FINE!
Или, может быть, вам нужно что-то вроде этого:
Class<List<String>> klazz =
(Class<List<String>>) new ArrayList<String>().getClass();
// WARNING! Type safety: Unchecked cast from
// Class<capture#1-of ? extends ArrayList> to Class<List<String>>
Что касается нереализованного во время выполнения примера, вы, похоже, хорошо разбираетесь, но в любом случае вот цитата из Обучающих программ по Java по универсальным , Fine Print : Общий класс является общим для всех его призывов :
Что печатает следующий фрагмент кода?
List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
Возможно, вы захотите сказать false
, но вы ошибаетесь. Он печатает true
, потому что все экземпляры универсального класса имеют один и тот же класс времени выполнения, независимо от их фактических параметров типа.
То есть нет такой вещи как List<String>.class
или List<Integer>.class
; есть только List.class
.
Это также отражено в литералах класса JLS 15.8.2
Литерал класса - это выражение, состоящее из имени класса, интерфейса, массива или типа примитива или псевдотипа void, за которым следуют .
и токен class
.
Обратите внимание на отсутствие каких-либо допусков для параметров / аргументов универсального типа. Кроме того, * 1 043 *
Ошибка времени компиляции, если происходит любое из следующего:
- Именованный тип является переменной типа или параметризованным типом, или массивом, тип элемента которого является переменной типа или параметризованным типом.
То есть, это также не компилируется:
void <T> test() {
Class<?> klazz = T.class; // DOESN'T COMPILE!
// Illegal class literal for the type parameter T
}
По сути, вы не можете использовать дженерики с литералами классов, потому что это просто не имеет смысла: они не имеют значения.