Что делает вопросительный знак в среднем параметре типа дженериков Java?

Это - маленький отрывок кода, взятого от некоторых примеров, которые сопровождают Стэнфордский Синтаксический анализатор. Я разрабатывал в Java в течение приблизительно 4 лет, но никогда не имел очень глубокого понимания того, на что этот стиль кода, как предполагается, указывает.

List<? extends HasWord> wordList = toke.tokenize();

Я не волнуюсь по поводу деталей кода. То, чем я смущен, - то, что точно универсальное выражение, как предполагается, передает на английском языке.

Кто-то может объяснить это мне?

199
задан Paŭlo Ebermann 11 August 2011 в 14:37
поделиться

5 ответов

? extends HasWord

означает «Класс / интерфейс, расширяющий HasWord ». Другими словами, HasWord или любой из его дочерних элементов ... в основном все, что будет работать с instanceof HasWord плюс null .

Говоря более техническим языком, ? extends HasWord - это ограниченный подстановочный знак, описанный в пункте 31 Эффективное третье издание Java , начиная со страницы 139. Та же глава из 2-го издания доступна в Интернете в виде PDF ; часть ограниченных подстановочных знаков - это элемент 28, начиная со страницы 134.

Обновление: ссылка PDF была обновлена, так как Oracle некоторое время назад удалил ее. Теперь он указывает на копию, размещенную в Школе электронной инженерии и информатики Лондонского университета королевы Марии.

Обновление 2: давайте подробнее рассмотрим, почему вы хотите использовать подстановочные знаки.

Если вы объявляете метод, сигнатура которого ожидает передачи в List , то единственное, что вы можете передать, - это List .

Однако, если указанная подпись была Список , то вместо этого вы можете передать List .

Обратите внимание на небольшую разницу между List и List . Как выразился Джошуа Блох: PECS = производитель-расширяет, потребитель-супер.

Это означает, что если вы передаете коллекцию, из которой ваш метод извлекает данные (т.е. коллекция создает элементы для использования вашим методом), вы должны использовать extends .Если вы передаете коллекцию, в которую ваш метод добавляет данные (т.е. коллекция использует элементы, созданные вашим методом), она должна использовать super .

Это может показаться запутанным. Однако вы можете увидеть это в команде List sort (которая представляет собой просто ярлык для версии Collections.sort с двумя аргументами). Вместо использования Comparator , на самом деле требуется Comparator . В этом случае Компаратор использует элементы списка List , чтобы изменить порядок самого списка.

213
ответ дан 23 November 2019 в 05:09
поделиться

На английском языке:

Это Список некоторого типа, расширяющий класс HasWord , в том числе HasWord

В общем случае ? в дженериках означает любой класс. И extends SomeClass указывает, что этот объект должен расширять SomeClass (или быть этим классом).

4
ответ дан 23 November 2019 в 05:09
поделиться

Знак вопроса означает «любой тип». Только ? означает

Любой тип, расширяющий Объект (включая Объект )

, в то время как ваш пример выше означает

Любой тип, расширяющий или реализующий HasWord (включая HasWord , если HasWord - неабстрактный класс)

58
ответ дан 23 November 2019 в 05:09
поделиться

List принимает любые конкретные классы, которые расширяют HasWord. Если у вас есть следующие классы...

public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }

... wordList может содержать ТОЛЬКО список либо As, либо Bs, либо смесь обоих, потому что оба класса расширяют одного родителя, либо null (который не проходит проверку на instanceof для HasWorld).

14
ответ дан 23 November 2019 в 05:09
поделиться

Возможно, поможет надуманный пример из «реального мира».

У меня на работе есть мусорные баки разного вкуса. Все урны содержат мусор, но некоторые урны являются специализированными и не вмещают все виды мусора.Итак, у нас есть Bin и Bin . Система типов должна гарантировать, что я не могу поместить свой HalfEatenSandwichRubbish ни в один из этих типов, но он может попасть в общую корзину Bin . Если бы я хотел поговорить о корзине из мусора , которая может быть специализированной, поэтому я не могу складывать несовместимый мусор, то это будет корзина .

(Примечание: ? Extends не означает доступ только для чтения. Например, я могу с надлежащими мерами предосторожности вынуть мусор из корзины неизвестного назначения, а затем положить его обратно в другое место. .)

Не уверен, насколько это помогает. Указатель на указатель при наличии полиморфизма не совсем очевиден.

11
ответ дан 23 November 2019 в 05:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: