Что означает знак вопроса в параметре типа generics Java?
Это небольшой fragment кода, взятый из некоторых примеров, которые сопровождают Стэнфордский парсер. Я развиваюсь на Java около 4 лет, но никогда не имел очень сильного понимания того, что должен указывать этот стиль кода.
List wordList = toke.tokenize();
Я не беспокоюсь о деталях кода. То, о чем я смущен, – это то, что, как предполагается, должно выражать родовое выражение на английском языке.
Может кто-то объяснить это мне?
- Эквивалент Try-with-resources в Java 1.6
- Заставить часовой пояс Java как GMT / UTC
- Исключение синтаксиса формата даты - «EEE MMM dd HH: mm: ss Z yyyy»
- Невозможно проанализировать строку DateTime с маркером AM / PM
- Как сделать AWT Button () и использовать ImageIcon (), Icon ()?
- Регистрация и использование пользовательского протокола java.net.URL
- Скомпилируйте код полностью в памяти с помощью javax.tools.JavaCompiler
- Группа захвата regex java
- Ошибка при попытке установить плагин
- правильная аннотация для спящего режима для байта
- Как сделать JAR-файл, содержащий файлы DLL?
- Как найти кодировку по умолчанию или кодировку в Java?
- Запустить почтовый клиент с приложением?
? 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
какого-то типа, который расширяет classHasWord
, включаяHasWord
В общем ли ?
в generics означает любой class. И extends SomeClass
указывает, что этот объект должен расширять SomeClass
(или быть этим classом).
Значок вопроса используется для определения подстановочных знаков . Оформить документацию Oracle о них: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html