Подтвердить что ты не робот

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?

С уважением,
Каспер ван ден Берг

пс. Сообщите мне, хотите ли вы видеть код внешнего универсального контейнера, который нуждается в информации этого типа; я отправлю его, если потребуется.

4b9b3361

Ответ 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>> выходов - также ошибочно - но это не наша вина.