Вопрос с собеседования · Java

Что такое generics в Java и зачем нужен wildcard ? extends / ? super?

JuniorДженерики
Коротко

Дженерики — проверка типов на компиляции без приведений вручную. Wildcard: ? extends T — из коллекции читают как T (производитель), ? super T — в коллекцию пишут T (потребитель). Правило PECS: Producer Extends, Consumer Super.

  • List<? extends Number> — можно получить Number, нельзя добавить Integer
  • List<? super Integer> — можно добавить Integer, читать только как Object
  • List<?> — только чтение как Object

А ещё Пример из JDK: Collections.copy(List<? super T> dest, List<? extends T> src)

Подробно

Зачем дженерики:

List names = new ArrayList();          // до Java 5
names.add(42);                         // компилятор молчит
String s = (String) names.get(0);      // ClassCastException в рантайме

List<String> names = new ArrayList<>();
names.add(42);                         // ошибка компиляции

Почему нужны wildcard. Дженерики инвариантны: List<Integer> не подтип List<Number>. Метод sum(List<Number>) не примет список Integer. Решение — sum(List<? extends Number>).

? extends T — за ссылкой может быть List<Integer> или List<Double>. Читать как Number безопасно, а добавить нельзя ничего (кроме null): компилятор не знает, какой именно тип там.

? super T — за ссылкой List<Integer>, List<Number> или List<Object>. Добавить Integer безопасно, а прочитать можно лишь Object.

PECS — источник данных объявляют через extends, приёмник через super:

static <T> void copy(List<? super T> dest, List<? extends T> src)

Что хотят услышать

  • Зачем дженерики.
  • Инвариантность и роль wildcard.
  • PECS с примером.

Частые ошибки

  • Пытаться добавлять элементы в ? extends.
  • Ждать доступности T.class из-за стирания типов.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Проверка типов на компиляции; по PECS из ? extends T читают, в ? super T пишут
  • ✗Дженерики проверяют типы во время выполнения
  • ✗Проверка типов на компиляции; по PECS в ? extends T пишут, из ? super T читают
  • ✗В List<? extends Number> можно добавить Integer

Что спросят дальше

  • Что такое type erasure?
  • Почему List<String> не является подтипом List<Object>?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования