TGViewer
Java: fill the gaps Java: fill the gaps @java_fillthegaps · 12.3K subscribers
Post #276 5.21K
Generics, часть 2: вопросики

В этой части разберём wildcards, и как дженерики работают с иерархиями.

Начнём с ответа на вопрос перед постом. Компилятор выдаст ошибку.

Почему так?

Пойдём от обратного и представим, что метод принимает List<Child>.

Внутри метода мы работаем со ссылкой на List<Parent>, значит в список можно добавить объект Parent. Если метод примет List<Child>, значит List<Child> тоже принимает объекты Parent. Что противоречит контракту, поэтому List<Child> никак не связан с List<Parent>.

Здесь разработчики дженериков учли неудачный опыт с массивами. Для массивов возможна такая ситуация:
🔸 Создаём переменную arr с массивом Parent:
Parent[] arr;

🔸 Присваиваем массив Child:
arr = new Child[2];

🔸 Добавляем в arr экземпляры Child и Parent:
arr[0] = new Child();
arr[1] = new Parent();

Вторая строка в рантайме бросит ArrayStoreException. Дженерики обрабатываются при компиляции, поэтому ошибок на этапе выполнения нет.

Wildcards

Для ситуаций, когда мы точно-точно не будем менять список, и нам только посмотреть, можно использовать wildcards:

void print(List<?> list)

Теперь метод принимает списки любых типов. Конкретный тип неизвестен, поэтому доступны только методы класса Object. Можно получить размер списка или вызвать для элементов toString.

❓Чем List<?> отличается от List?

В List<?> компилятор не даст ничего добавить, а для List ограничений нет.

❓Как вызвать нужные методы для List<?>?

Тип в списке можно уточнить:

void print(List<? extends Parent> list)

Теперь метод принимает только List<Parent> и List<Child>, плюс есть доступ к методам Parent. Но менять список всё ещё нельзя.

Буквы и вопросики

Есть два способа ограничить типы списков:

▫️ <T extends Parent> void test(List<T> list)
▫️ void test(List<? extends Parent> list)

Чем они отличаются?

T - это конкретный тип элементов списка, поэтому в список можно добавить объекты типа Т. В листе с вопросиком конкретный тип НЕ известен, и компилятор НЕ даст добавить новые элементы.

extends и super

В иерархии Object - Parent - Child можно ограничить типы с разных сторон.

extends - ограничение иерархии "сверху"
? extends Parent: допустимы Parent, Child и наследники Child

super
- ограничение типов "снизу"
? super Parent принимает Parent и родителей Parent вплоть до Object
  • ❤ 2
More from @java_fillthegaps
  1. Apr 30, 2026Get Your Hands Dirty on Clean Architecture: отзыв на книгу Когда я подняла тему чистой арх…
  2. Apr 27, 2026​Clean Architecture: отзыв на книгу Наконец-то дочитала книгу Clean Architecture Роберта М…
  3. Mar 4, 2026Как переиспользовать контекст в интеграционных тестах Сегодня расскажу базовый минимум для…
  4. Mar 4, 2026Post #660
  5. Mar 4, 2026Тестовый контекст поднимается 2 минуты. У нас 4 класса с интеграционными тестами, их конфи…
  6. Feb 25, 2026Чистая архитектура. Главы 3-5 Продолжаем спидран по Clean Architecture Роберта Мартина. ⭐️…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →