Почему подстановочные знаки необходимы в Java generics?

#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 .