Вопрос проверяет понимание того, как generics влияют на байткод и какие механизмы используются для сохранения типовой безопасности.
На уровне байткода generics реализованы через стирание типов и приведение типов. Компилятор добавляет cast там, где это необходимо. JVM не знает о generics и работает с обычными типами. Дополнительная информация о generics хранится только в metadata класса. Типовая безопасность обеспечивается на этапе компиляции.
Хотя generics выглядят как часть языка, JVM о них почти ничего не знает.
Реализация generics в Java основана на type erasure и добавлении проверок типов компилятором.
Компилятор выполняет несколько шагов.
Стирание типов
T → Object
T extends Number → Number
Добавление приведения типов
Object → конкретный тип при чтении
Пример:
List<String> list = new ArrayList<>();
String s = list.get(0);
Фактически в байткоде:
Object o = list.get(0);
String s = (String) o;
Хотя JVM не использует generics, информация о них сохраняется:
В class-файле
В metadata
Доступна через reflection (getGenericType)
Эта информация:
не влияет на выполнение
используется инструментами и фреймворками
ClassCastExceptionЕсли generics нарушены через raw-типы:
List list = new ArrayList<String>();
list.add(10);
Ошибка возникнет:
не при добавлении
а при чтении элемента
Generics — это механизм compile-time безопасности. В runtime они реализуются через обычные типы и приведения.