Дженерики Java вводят стирание: когда и что происходит?

233
задан Radiodef 19 June 2018 в 08:24
поделиться

4 ответа

Стирание типа относится использование из дженериков. Существуют определенно метаданные в файле класса, чтобы сказать, является ли метод/тип универсальным, и что ограничения и т.д., Но когда дженерики , использовал , они преобразовываются в проверки времени компиляции и броски времени выполнения. Так этот код:

List<String> list = new ArrayList<String>();
list.add("Hi");
String x = list.get(0);

компилируется в [1 111]

List list = new ArrayList();
list.add("Hi");
String x = (String) list.get(0);

Во время выполнения нет никакого способа узнать, что T=String для объекта списка - что информации не стало.

..., но эти List<T> сам интерфейс все еще рекламирует себя как являющийся универсальным.

РЕДАКТИРОВАНИЕ: Просто для уточнения компилятор действительно сохраняет информацию о переменная являющийся List<String> - но Вы все еще не можете узнать что T=String для самого объекта списка.

234
ответ дан wchargin 23 November 2019 в 03:32
поделиться

Если у Вас есть поле, которое является универсальным типом, его параметры типа компилируются в класс.

, Если у Вас есть метод, который берет или возвращает универсальный тип, те параметры типа компилируются в класс.

Эта информация - то, что использование компилятора сказать Вам, что Вы не можете передать Box<String> empty(Box<T extends Number>) метод.

API является сложным, но можно осмотреть эту информацию о типе через API Reflection с методами как getGenericParameterTypes , getGenericReturnType , и, для полей, getGenericType .

, Если у Вас есть код, который использует универсальный тип, компилятор вводит броски по мере необходимости (в вызывающей стороне) для проверки типов. Сами родовые объекты являются просто необработанным типом; параметризованный тип "стирается". Так, когда Вы создаете new Box<Integer>(), нет никакой информации о Integer класс в эти Box объект.

FAQ Angelika Langer является лучшей ссылкой, я видел Дженерики Java.

33
ответ дан erickson 23 November 2019 в 03:32
поделиться

Дженерики на Языке Java действительно хорошее руководство по этой теме.

Дженерики реализованы компилятором Java как преобразование фронтенда, названное стиранием. Можно (почти) думать о нем как о переводе от источника к источнику, посредством чего универсальная версия loophole() преобразовывается в неуниверсальную версию.

Так, это во время компиляции. JVM никогда не будет знать, который ArrayList Вы использовали.

я также рекомендовал бы ответ г-на Skeet на , Каково понятие стирания в дженериках в Java?

13
ответ дан try-catch-finally 23 November 2019 в 03:32
поделиться

Стирание типа происходит во время компиляции. То, что означает стирание типа, - то, что оно забудет об универсальном типе, не о каждом типе. Кроме того, все еще будут метаданные о типах, являющихся универсальным. Например

Box<String> b = new Box<String>();
String x = b.getDefault();

преобразовывается в

Box b = new Box();
String x = (String) b.getDefault();

во время компиляции. Можно получить предупреждения, не потому что компилятор знает о том, из чего тип является дженериком, но наоборот, потому что это не знает достаточно так, это не может гарантировать безопасность типов.

Кроме того, компилятор действительно сохраняет информацию о типе о параметрах на вызове метода, который можно получить через отражение.

Этот руководство является лучшим, я нашел на предмете.

6
ответ дан Vinko Vrsalovic 23 November 2019 в 03:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: