Что означает знак вопроса в параметре типа Java generics?



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



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


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



может кто-нибудь объяснить это мне?

560   6  

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 ' s sort команда (которая является просто ярлыком для двух-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 a Binofмусор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

    Ничего не найдено.