? 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символу для того, щоб впорядкувати сам Список.