В качестве предисловия к моему вопросу, обратите внимание, что я знаю, что такое стирание типов. Я чувствую необходимость заявить об этом, так что полезные ответы не будут скрыты в основных объяснениях.
Я хотел бы получить объект класса для класса List. Для не универсального c типа я бы использовал литерал класса, такой как String.class, но для List, хотя я могу получить правильное поведение, я все равно получаю предупреждения о том, что я делаю это неправильно.
Насколько я понимаю, объект класса для List будет иметь тип Class<List>
, но даже записывая этот тип,
Class<List> c = null;
выдает предупреждение: «Необработанное использование параметризованного класса« List »». Из-за стирания типа объект класса не может знать об элементах списка, поэтому мое следующее предположение будет
Class<List<?>> c = null;
, которое в качестве типа будет принято. Затем мне нужно получить объект класса, но все попытки записать литерал класса заканчиваются неудачей:
Class<List<?>> l = List.class;
выдает ошибку жесткого типа, в то время как
Class<List<?>> l = List<?>.class;
говорит: «Не могу выберите из параметризованного типа ".
Class<List<?>> l = (Class<List>)List.class;
Сбой с той же ошибкой жесткого типа, что и без преобразования (ожидается, так как приведение является избыточным), а
Class<List<?>> l = (Class<List<?>>)List.class;
говорит" необратимые типы " .
Далее я попробовал следующий недопустимый фрагмент кода, чтобы узнать что-то из ошибки компилятора:
List<?> l = new ArrayList<>();
int x = l.getClass();
Теперь компилятор выдает ошибку типа для Class<? extends java.util.List>
- игнорирование расширений "часть на мгновение, что очевидно, так как getClass()
может вернуть подкласс, это говорит мне, что .getClass()
хочет говорить только о необработанном типе List, а не List<?>
или подобном. В некотором смысле это кажется мне правильным, поскольку объект класса представляет любой экземпляр List, а не «списки, тип которых неизвестен». Однако теперь я вернулся к исходной точке, потому что простое записывание необработанного типа дает предупреждение, поэтому я, очевидно, не собираюсь этого делать (я понимаю, что необработанные типы можно использовать для работы с устаревшим кодом, но я не делая этого здесь).
Я понимаю, что мог бы выбросить всю информацию о типе класса stati c об объекте класса следующим образом:
Class<?> c = List.class;
Но это часто неосуществимо, и На самом деле я пытаюсь решить более крупную проблему, где мне нужна эта информация о типах.
Хотя я знаю, что могу легко отключить предупреждения или использовать аналогичные грязные приемы, я хотел бы знать, какой правильный способ получить объект класса для List.