Что означает знак вопроса в параметре типа Java generics?
Это небольшой фрагмент кода, взятый из некоторых примеров, которые сопровождают Стэнфордский парсер. Я разрабатываю Java около 4 лет, но никогда не имел очень сильного понимания того, что этот стиль кода должен указывать.
List<? extends HasWord> wordList = toke.tokenize();
Я не беспокоюсь о деталях кода. Что меня смущает, так это то, что именно общее выражение должно передавать на английском языке.
может кто-нибудь объяснить это мне?
6 ответов:
? extends HasWordозначает " класс / интерфейс, который расширяет
HasWord."Другими словами,HasWordсебя или любого из своих детей... в основном все, что будет работать сinstanceof HasWordплюсnull.в более технических терминах,
? extends HasWordявляется ограниченным подстановочным знаком, охватываемым пунктом 31 эффективное Java 3-е издание, начиная со страницы 139. Та же самая глава из 2-го издания -доступно онлайн в формате PDF; часть на ограниченных подстановочных знаках-это пункт 28, начиная с страница 134.обновление: ссылка PDF была обновлена с тех пор, как Oracle удалил ее некоторое время назад. Теперь он указывает на копию, размещенную в Лондонской школе электронной инженерии и компьютерных наук Университета Королевы Марии.
Update 2: Давайте рассмотрим немного подробнее, почему вы хотите использовать подстановочные знаки.
если вы объявите метод, подпись которого ожидает, что вы передадите в
, если сказал, что подписьList<HasWord>, тогда единственное, что вы можете пройти вList<HasWord>.List<? extends HasWord>тогда вы могли бы пройти в .обратите внимание, что есть тонкая разница между
List<? extends HasWord>иList<? super HasWord>. Как выразился Джошуа блох: PECS = производитель-расширяется, потребитель-супер.это означает, что если вы передаете коллекцию, из которой ваш метод извлекает данные (т. е. коллекция создает элементы для вашего метода), вы должны использовать
extends. Если вы передаете в коллекцию, что ваш метод добавляет данные чтобы (т. е. коллекция потребляет элементы, которые создает ваш метод), он должен использоватьsuper.это может показаться странным. Тем не менее, вы можете увидеть его в
List' ssortкоманда (которая является просто ярлыком для двух-arg версии коллекций.род.) Вместо того, чтобыComparator<T>, это на самом деле занимаетComparator<? super T>. В этом случае компаратор потребляет элементыListдля того, чтобы изменить сам список.
вопросительный знак-это обозначение для 'любого типа'. означает
любой тип удлиняя
Object(включаяObject)в то время как ваш пример выше означает
любой тип расширения или реализации
HasWord(включаяHasWordЕслиHasWord- это не абстрактный класс)
List<? extends HasWord>принимает любые конкретные классы, которые расширяют 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).
возможно, надуманный пример "реального мира"поможет.
на работе у нас есть мусорные баки, которые приходят в разных вкусах. Все бункеры содержат мусор, но некоторые бункеры являются специалистами и не принимают все виды мусора. Так что у нас есть
Bin<CupRubbish>иBin<RecylcableRubbsih>. Система типов должна убедиться, что я не могу поставить свойHalfEatenSandwichRubbishв любой из этих типов, но он может пойти в общий мусорный бак " Bin. If I wanted to talk about aBinofмусорwhich may be a specialist so I can't put in incompatible rubbish, then that would beБин`.(Примечание:
? extendsне означает только для чтения. Например, я могу с должными предосторожностями вынуть кусок мусора из мусорного ведра неизвестной специальности и позже положить его обратно в другое место.)Не уверен, насколько это помогает. Указатель на указатель в присутствии полиморфизма не совсем очевиден.
На Английском Языке:
это
Listнекоторого типа, который расширяет классHasWord, включаяHasWordв целом
?в дженериках означает любой класс. А тоextends SomeClassуказывает, что этот объект должен продлитьSomeClass(или этого класса).
знак вопроса используется для определения шаблоны. Проверьте документацию Oracle о них:http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
Comments