Java-литье ".class" -оператор, используемый для общего типа, например. List, "Class <List <? >>" и "Class <List <Integer>>"
Я использую .class
-оператор для предоставления информации об содержащем типе универсальному классу. Для не-общих содержащихся типов, например. Integer.class
, это работает без проблем. Но с включенным типом, являющимся общим, например. List<Integer>.class
или List.class
, это приводит к ошибкам компиляции времени в классе.
Есть способ обойти ошибки, но мне интересно, что здесь происходит. Может кто-нибудь объяснить, что происходит?, почему все так, как есть?, и что лучший способ обойти проблему?
Следующие строки демонстрируют проблему:
Обратите внимание, что внешний общий тип ожидает Class<T>
в качестве параметра, поэтому в этом случае Class<List<Integer>>
.
Class<Integer> tInt = Integer.class; // Works as expected.
Class<List> tList = List.class; // Works with warning, but is not
// what i'm looking for.
Class<List<Integer>> tListInt1 = List.class; // Error
Class<List<Integer>> tListInt2 = (Class<List<Integer>>) List.class; // Error
Class<List<?>> tListGeneric = (Class<List<Integer>>) List.class; // Error
Следующая строка работает:
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
Почему декларации tListInt2
и tListGeneric
дают и ошибки?
Почему угасание, а затем подавление с tListInt3
не приводит к ошибке?
Есть ли лучший способ объявить tListInt3
?
С уважением,
Каспер ван ден Берг
пс. Сообщите мне, хотите ли вы видеть код внешнего универсального контейнера, который нуждается в информации этого типа; я отправлю его, если потребуется.
Ответы
Ответ 1
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
что не работает. вы, вероятно, имели в виду
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class)List.class);
мы всегда можем отбрасывать от одного типа к другому с помощью up-cast then down-cast
Integer x = (Integer)(Object)"string";
Тип List.class
- Class<List>
; он не является подтипом/супертипом Class<List<Whatever>>
, поэтому прямой бросок между двумя типами является незаконным.
Можно утверждать, что Class<List<Integer>>
не существует - существует только класс для List
; нет такого класса для List<Integer>
(который на самом деле просто List
во время выполнения)
Однако это недостаток системы типа Java; на практике нам нужны такие вещи, как Class<List<Integer>>
. Наше решение - литье и притворство Class<List<Int>>
выходов - также ошибочно - но это не наша вина.