Стирание типа относится использование из дженериков. Существуют определенно метаданные в файле класса, чтобы сказать, является ли метод/тип универсальным, и что ограничения и т.д., Но когда дженерики , использовал , они преобразовываются в проверки времени компиляции и броски времени выполнения. Так этот код:
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
для самого объекта списка.
Если у Вас есть поле, которое является универсальным типом, его параметры типа компилируются в класс.
, Если у Вас есть метод, который берет или возвращает универсальный тип, те параметры типа компилируются в класс.
Эта информация - то, что использование компилятора сказать Вам, что Вы не можете передать Box<String>
empty(Box<T extends Number>)
метод.
API является сложным, но можно осмотреть эту информацию о типе через API Reflection с методами как getGenericParameterTypes
, getGenericReturnType
, и, для полей, getGenericType
.
, Если у Вас есть код, который использует универсальный тип, компилятор вводит броски по мере необходимости (в вызывающей стороне) для проверки типов. Сами родовые объекты являются просто необработанным типом; параметризованный тип "стирается". Так, когда Вы создаете new Box<Integer>()
, нет никакой информации о Integer
класс в эти Box
объект.
FAQ Angelika Langer является лучшей ссылкой, я видел Дженерики Java.
Дженерики на Языке Java действительно хорошее руководство по этой теме.
Дженерики реализованы компилятором Java как преобразование фронтенда, названное стиранием. Можно (почти) думать о нем как о переводе от источника к источнику, посредством чего универсальная версия
loophole()
преобразовывается в неуниверсальную версию.
Так, это во время компиляции. JVM никогда не будет знать, который ArrayList
Вы использовали.
я также рекомендовал бы ответ г-на Skeet на , Каково понятие стирания в дженериках в Java?
Стирание типа происходит во время компиляции. То, что означает стирание типа, - то, что оно забудет об универсальном типе, не о каждом типе. Кроме того, все еще будут метаданные о типах, являющихся универсальным. Например
Box<String> b = new Box<String>();
String x = b.getDefault();
преобразовывается в
Box b = new Box();
String x = (String) b.getDefault();
во время компиляции. Можно получить предупреждения, не потому что компилятор знает о том, из чего тип является дженериком, но наоборот, потому что это не знает достаточно так, это не может гарантировать безопасность типов.
Кроме того, компилятор действительно сохраняет информацию о типе о параметрах на вызове метода, который можно получить через отражение.
Этот руководство является лучшим, я нашел на предмете.