Это небольшой фрагмент кода, взятый из некоторых примеров, сопровождающих Stanford Parser. Я занимался разработкой на Java около 4 лет, но никогда не имел четкого понимания того, на что должен указывать этот стиль кода.
List<? extends HasWord> wordList = toke.tokenize();
Я не беспокоюсь о деталях кода. Что меня смущает, так это то, что именно родовое выражение должно передавать на английском языке.
Может кто-то объяснить это мне?
Ответы:
означает «класс / интерфейс, который расширяется
HasWord
». Другими словами,HasWord
сам или любой из его детей ... в основном все, что будет работать сinstanceof HasWord
плюсомnull
.В более технических терминах
? extends HasWord
это ограниченный подстановочный знак, описанный в пункте 31 « Эффективного Java 3-е издание» , начиная со страницы 139. Та же глава из 2-го издания доступна онлайн в формате PDF ; часть на ограниченных подстановочных знаках - это пункт 28, начиная со страницы 134.Обновление: PDF-ссылка была обновлена, так как Oracle удалила ее некоторое время назад. Это теперь указывает на копию, размещенную в Университете королевы Марии Лондонской школы электронной инженерии и компьютерных наук.
Обновление 2: давайте более подробно рассмотрим, почему вы хотите использовать подстановочные знаки.
Если вы объявляете метод, чья сигнатура ожидает от вас передачи
List<HasWord>
, то единственное, что вы можете передать, это aList<HasWord>
.Однако, если указанная подпись была,
List<? extends HasWord>
тогда вы могли бы передатьList<ChildOfHasWord>
вместо.Обратите внимание, что между
List<? extends HasWord>
и есть небольшая разницаList<? super HasWord>
. Как сказал Джошуа Блох: PECS = производитель-расширяет, потребитель-супер.Это означает, что если вы передаете коллекцию, из которой ваш метод извлекает данные (т. Е. Коллекция создает элементы для вашего метода), вы должны использовать ее
extends
. Если вы передаете коллекцию, в которую ваш метод добавляет данные (т. Е. Коллекция использует элементы, которые создает ваш метод), его следует использоватьsuper
.Это может показаться странным. Тем не менее, вы можете увидеть его в
List
«Ssort
команды (это просто ярлык версии два-Arg из Collections.sort). Вместо того, чтобы взятьComparator<T>
, это на самом деле беретComparator<? super T>
. В этом случае Компаратор потребляет элементы дляList
того, чтобы изменить порядок самого Списка.источник
List<HasWord>
это именно то, что вы описываете: список, который содержит любые объекты,x
для которыхx instanceof HasWord
возвращает true, иnull
. Вам не нужно подстановочный знак для этого. Подстановочный знак означает, что он также может быть списком другого типа, если этот тип является подтипомHasWord
. (Извините за поздний комментарий.)Знак вопроса означает «любой тип».
?
одни средствав то время как ваш пример выше означает
источник
public Set<Class<?>> getClasses()
значит? В чем разницаSet<Class>
? Я смотрюjavax.ws.rs.core.Application
.List<? extends HasWord>
принимает любые конкретные классы, расширяющие HasWord. Если у вас есть следующие классы ......
wordList
может содержать ТОЛЬКО список As или B или их комбинацию, потому что оба класса расширяют одного и того же родителя илиnull
(который не проверяет instanceofHasWorld
).источник
List<? extends Collection<String>> list = new ArrayList<List<String>>();
.List<HasWord>
так же хорошо для этого. Дело в том, что эта переменная может содержатьList<A>
или,List<B>
а такжеList<HasWord>
.Возможно, придуманный пример из "реального мира" поможет.
У меня на работе есть мусорные баки, которые бывают разных вкусов. Все контейнеры содержат мусор, но некоторые контейнеры являются специализированными и не принимают все виды мусора. Так у нас
Bin<CupRubbish>
и естьBin<RecylcableRubbish>
. Система типов должна удостовериться, что я не могу положить свойHalfEatenSandwichRubbish
ни в один из этих типов, но она может войти в общую корзину для мусораBin<Rubbish>
. Если бы я хотел поговорить проBin
изRubbish
которых может быть специализированы , поэтому я не могу поставить в несовместимом мусоре, то это было быBin<? extends Rubbish>
.(Примечание:
? extends
не означает «только для чтения». Например, я могу с надлежащими мерами предосторожности вынуть кусок мусора из мусорной корзины неизвестной специальности, а затем положить его в другое место.)Не уверен, насколько это помогает. Указатель на указатель при наличии полиморфизма не совсем очевиден.
источник
По-английски:
Вообще,
?
в дженериках подразумевается любой класс. Иextends SomeClass
указывает, что этот объект должен расширятьсяSomeClass
(или быть этим классом).источник
Знак вопроса используется для определения подстановочных знаков . Ознакомьтесь с документацией Oracle о них: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html.
источник