? extends HasWord
означає "Клас / інтерфейс, який розширюється HasWord
." Іншими словами, HasWord
сама або будь-яка її дитина ... в основному все, що працювало б з instanceof HasWord
плюсом null
.
Більш технічно, ? extends HasWord
це обмежений підстановочний код, який розглядається в пункті 31 Ефективної Java 3-го видання , починаючи з сторінки 139. Цей самий розділ з другого видання доступний в Інтернеті як PDF ; Частина на обмежених символах - пункт 28, починаючи зі сторінки 134.
Оновлення: посилання PDF було оновлено, оскільки Oracle деякий час його видалив. Тепер він вказує на копію, яку розмістила Лондонська школа електронної інженерії та комп’ютерних наук з університету королеви Мері.
Оновлення 2: Давайте детальніше розберемося, чому ви хочете використовувати подстановочні символи.
Якщо ви заявляєте метод, підпис якого очікує, що ви перейдете List<HasWord>
, то єдине, що ви можете передати - це List<HasWord>
.
Однак, якщо згаданий підпис був List<? extends HasWord>
тоді, ви можете List<ChildOfHasWord>
замість цього передати .
Зауважте, що між List<? extends HasWord>
і та є незначна різниця List<? super HasWord>
. Як сказав Джошуа Блох: PECS = виробник розширює, споживач - супер.
Це означає, що якщо ви передаєте колекцію, з якої ваш метод витягує дані (тобто колекція створює елементи для використання вашого методу), ви повинні використовувати extends
. Якщо ви передаєте колекцію, до якої ваш метод додає дані (тобто колекція споживає елементи, створені вашим методом), він повинен використовувати super
.
Це може здатися заплутаним. Однак ви можете побачити його в команді List
's sort
(що є лише ярликом до двоаргументованої версії Collections.sort). Замість того, щоб взяти a Comparator<T>
, він насправді бере a Comparator<? super T>
. У цьому випадку компаратор споживає елементи List
символу для того, щоб впорядкувати сам Список.