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

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

List wordList = toke.tokenize(); 

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

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

 ? extends HasWord 

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

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

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

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

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

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

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

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

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

Вопросительный знак является означающим для «любого типа». ? один означает

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

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

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

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

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

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

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

На работе у нас есть мусорные баки, которые приходят в разные вкусы. Все бункеры содержат мусор, но некоторые бункеры являются специалистами и не берут все виды мусора. Итак, у нас есть Bin и Bin . Система типов должна убедиться, что я не могу поместить свой HalfEatenSandwichRubbish в любой из этих типов, но он может попасть в общий мусорный ящик “ Bin . If I wanted to talk about a . If I wanted to talk about a Бунке Мусора, which may be a specialist so I can't put in incompatible rubbish, then that would be Бин`.

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

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

На английском:

Это List какого-то типа, который расширяет class HasWord , включая HasWord

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

Значок вопроса используется для определения подстановочных знаков . Оформить документацию Oracle о них: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

  • Как добавить локальную зависимость .jar-файла для файла build.gradle?
  • Могу ли я передать массив в качестве аргументов метода с переменными аргументами в Java?
  • Изменение размера изображения и отображение в JPanel или JLabel без потери качества
  • Как установить длинный путь Java classpath в Windows?
  • Возвращает несколько значений из метода Java: почему нет объектов n-кортежей?
  • Безстоящие и Stateful Enterprise Java Beans
  • Как найти неиспользуемый / мертвый код в java-проектах
  • Внутренний class Java и статический вложенный class
  • Правильное использование флеша () в JPA / Hibernate
  • Должно ли соединение базы данных оставаться открытым все время или только при необходимости открываться?
  • Java-массив с элементами более 4 ГБ
  • Давайте будем гением компьютера.