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

Почему нельзя создать массив параметризованного типа (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 с дженериками создают такой массив — отсюда предупреждения

Подробно

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

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

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

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

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

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

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

Показать варианты и ответ
  • ✗Это разрешено начиная с Java 8
  • ✗Массивы умеют хранить только примитивы
  • ✓Массивы проверяют тип в рантайме, а дженерики стёрты — проверка была бы невозможна
  • ✗Дженерики проверяются в рантайме, а массивы — только компилятором, и типы бы конфликтовали

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

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

Разбор темы

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

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

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

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

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