Каковы исключения для ввода стирания в Java?

Я видел, как в некоторых местах в Интернете упоминалось, что в некоторых ситуациях можно использовать API отражения для получения информации об общих типах данных, которые, как я думал, будут потеряны из-за стирания типа.

Я ищу полный список ситуаций, когда стирание типа не завершено, т.е. что-то все еще доступно через отражение. Хороший список примеров и связанный с ними код отражения, который может получить общие типы, был бы превосходным.

ОБНОВЛЕНИЕ http://tutorials.jenkov.com/java-reflection/generics.html были именно те примеры, которые я искал.


person ams    schedule 06.08.2012    source источник
comment
если вы проголосовали за закрытие этого вопроса, пожалуйста, прокомментируйте и скажите мне, почему?   -  person ams    schedule 06.08.2012
comment
ссылки на эти места были бы полезны.   -  person Thilo    schedule 06.08.2012
comment
@Thilo stackoverflow.com/questions/4713438/type-erasure-in-java является примером места, в котором упоминается, что не вся информация о типе потеряна.   -  person ams    schedule 06.08.2012


Ответы (2)


Я думаю, что это просто сводится к этому:

  • Ни один экземпляр объекта не хранит никакой информации о типе.

  • Классы, однако, сохраняют все свои универсальные подписи (иначе у вас не было бы никакой проверки универсальных типов во время компиляции).

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

Пример:

 class MyList extends ArrayList<MyObject>{}

 List<MyObject> x = new MyList();

Отражение скажет вам, что это список MyObject (поскольку эта информация скомпилирована в класс MyList).

но

List<MyObject> x = new ArrayList<MyObject>();

Отражение не даст вам ничего полезного (поскольку класс ArrayList ничего не знает о MyObject).

person Thilo    schedule 06.08.2012
comment
+1 Причина, по которой сохраняется любая общая информация, заключается в том, что компилятор javac выполняет свою работу. например вы должны быть в состоянии скомпилировать код, используя дженерики в уже скомпилированном коде. - person Peter Lawrey; 06.08.2012
comment
В дополнение к суперклассу, дженерики в типах неприватных полей, а также типы аргументов и возвращаемых значений методов также присутствуют для целей проверки типов. - person newacct; 06.08.2012
comment
Да, все это является частью определения класса. Приведенный выше пример не был исчерпывающим. Но обратите внимание, что во всех этих случаях дженерики доступны для определения поля/аргумента/типа возвращаемого значения (сигнатуры), а не для фактического значения времени выполнения любого назначенного им объекта. - person Thilo; 06.08.2012

Общая идея заключается в том, что если вы создаете именованный или анонимный класс, который является подклассом универсального типа с определенными типами для параметров типа, то подкласс не является универсальным и не подлежит стиранию типа. Предполагая, что вы можете получить объект Class для подкласса, вы можете использовать отражение этого объекта, чтобы узнать, каковы типы параметров.

Если подумать, это не совсем «исключение» из правила стирания. Скорее, это делает так, чтобы рассматриваемый класс не был родовым, путем его явного овеществления.

person Stephen C    schedule 06.08.2012
comment
чтобы узнать, какие типы параметров Нет, вы узнаете параметры типа суперкласса, который он расширяет. - person newacct; 06.08.2012