#java #generics #wildcard
#java #generics #подстановочный знак
Вопрос:
Если я правильно понял, единственная цель Java wildcards — ввести ковариацию и контравариантность между универсальными типами. Я рассматриваю подстановочные знаки Java как трюк компилятора для реализации этих двух концепций. Я прав или в этом есть что-то еще?
Ответ №1:
По большей части это верно, но на самом деле это не «уловка компилятора», а скорее языковая функция, гарантирующая во время компиляции, что (если отбросить непроверенные приведения / предупреждения) вы никогда не сможете оказаться в состоянии с несовместимыми типами во время выполнения.
Компилятор можно было бы легко написать так, чтобы он слепо принимал такой ковариантный универсальный код без подстановочных знаков, но у вас не было бы гарантии, что вы не столкнетесь с ClassCastException
(или несколькими) позже в строке.
Ответ №2:
Да, вы в принципе правы. Но я бы не назвал это трюком компилятора (в конце концов, Java Generics — это большой трюк компилятора, и ничего больше).
Подстановочные знаки — это концепция надежной системы типов; они гарантируют, что написанный вами код, который компилируется и не использует приведения, будет успешным во время выполнения. Таким образом, подстановочные знаки — это не трюк; они являются вполне допустимым способом выражения различий в использовании сайта.
Единственный критический момент заключается в том, что подстановочные знаки не допускают отклонения сайта объявления, как это позволяет, например, C #.
Комментарии:
1. Еще одна вещь, которая меня немного смущает, — это то, как правильно читать подстановочный знак. Например, я прочитал это <? extends T> как ‘набор типов, которые расширяют T’. Я рассматриваю это как «фиктивный тип», используемый компилятором. Я прав? Спасибо!
2. @Kami: Ну, вы можете называть это и так. Однако сам по себе подстановочный знак не имеет смысла. Скорее читайте это как единое целое с типом, т. е.:
X<? extends T>
это набор всех универсальныхX<S>
типов, параметром типа которыхS
является класс, который расширяетсяT
.