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

Почему нельзя создать массив параметризованного типа (new List<String>[10] или new T[n])?

SeniorДженерики
Ещё спрашивают так:
  • Что такое heap pollution?
  • Почему нельзя создать массив параметризованного типа и что такое heap pollution?
Коротко

Массивы ковариантны и знают тип элемента в рантайме (запись не того типа — ArrayStoreException сразу). Дженерики инвариантны и стёрты. Массив дженериков не смог бы проверить запись — неверный объект попал бы внутрь, и ClassCastException вылез бы далеко, в чужом коде. Это и есть heap pollution: переменная параметризованного типа ссылается на объект другого типа.

  • Решение — List<T> вместо T[]
  • Внутри коллекций: (T[]) new Object[n] с аккуратностью (как в ArrayList)
  • Или передать Class<T> / IntFunction<T[]>: Array.newInstance, toArray(String[]::new)

А ещё Varargs с дженериками создают такой массив — отсюда предупреждения

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

Подробно

Массив знает свой тип элемента в рантайме и проверяет вставку (ArrayStoreException). У дженериков тип стёрт, поэтому массив дженериков не смог бы проверить элемент — туда попал бы объект неверного типа, а ClassCastException всплыл бы позже в неожиданном месте. Штатное решение — List<T> вместо массива; если массив реально нужен, его делают через Array.newInstance с Class-токеном.

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

  • Конфликт моделей массивов и дженериков.
  • Определение heap pollution.
  • Обходные пути.

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

  • Создавать new T[] внутри generic-кода.
  • Глушить unchecked-варнинг широко вместо узкого @SuppressWarnings.

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

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

Показать варианты и ответ
  • ✓Массивы reifiable и ковариантны, дженерики стёрты и инвариантны; иначе вышел бы heap pollution — массив принял бы элемент не того типа без ArrayStoreException, а ClassCastException вылез бы позже
  • ✗Это разрешено начиная с Java 8
  • ✗Массивы умеют хранить только примитивы
  • ✗JVM запрещает любые массивы объектов

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

  • Как создать generic-массив через рефлексию?
  • Что такое ковариантность массивов?
  • Что такое reifiable-тип и какие типы к ним относятся?
  • Зачем компилятор генерирует bridge-методы?

Разбор темы

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

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

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

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

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