Получить доступ

Что невозможно из-за стирания типов?

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

В рантайме параметра типа нет, поэтому нельзя: new T(), new T[n], instanceof List<String>, статическое поле типа T, перегрузка m(List<String>) и m(List<Integer>) (одинаковая стёртая сигнатура), catch (T e).

  • Причина — совместимость с кодом до Java 5
  • Компилятор вставляет приведения, в байт-коде Object или верхняя граница
  • Обход — передать Class<T>, Supplier<T>, TypeReference (Jackson)

А ещё Тип сохраняется в сигнатурах классов и полей — его читают через рефлексию

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Стирание было платой за совместимость с кодом, написанным до появления дженериков: компилятор проверяет типы и вставляет приведения, а в байткоде остаётся обычный Object или верхняя граница. Отсюда весь список ограничений, включая невозможность создать массив параметризованного типа и запрет на обобщённые классы исключений — блок catch работает в рантайме и не смог бы различить типы. Статическое поле невозможно потому, что оно принадлежит классу, общему для всех параметризаций. Обходной приём, который стоит назвать: передавать Class<T> в конструктор и создавать объекты рефлексией, либо принимать фабрику Supplier<T>. Использование T в сигнатурах методов, разумеется, работает — на этом дженерики и построены.

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

  • Перечень ограничений.
  • Причина стирания.
  • Обходные пути.

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

  • Пытаться сделать обобщённый класс исключения.
  • Забывать, что информация о параметре в полях и сигнатурах всё же сохраняется в метаданных и доступна рефлексии.

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

Несколько верных вариантов. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Создать экземпляр параметра типа: new T()
  • ✓Проверить obj instanceof List<String>
  • ✓Объявить статическое поле типа параметра T в обобщённом классе
  • ✗Использовать параметр типа в качестве типа возвращаемого значения метода

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

  • Как обойти невозможность new T()?
  • Почему нельзя создать массив List<String>[]?

Разбор темы

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

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем