Заявление, которое вы цитируете, верно: компилятор использует информацию об общем типе внутри процесса компиляции, генерируя ошибки, связанные с типом, при обработке источников. Затем, как только проверка выполняется, компилятор генерирует стильный байт-код, при этом все ссылки на типовые типы заменяются на их стирание соответствующего типа.
Этот факт становится очевидным, когда вы смотрите на типы через отражение: все интерфейсы, классы и функции становятся неэквивалентными, причем все типы, привязанные к параметрам типового типа, заменяются не общим типом, основанным на ограничениях общего типа указанных в исходном коде. Хотя API-интерфейс отражения имеет положения для доступа к некоторой информации, связанной с генериками * во время выполнения, виртуальная машина не может проверить точный общий тип для совместимости при доступе к вашим классам через отражение.
Например, если вы сделаете член класса типа List<String>
и попробуйте установить List<Integer>
в него, компилятор будет жаловаться. Если вы попытаетесь сделать то же самое через отражение, однако, компилятор не собирается выяснить, и код будет терпеть неудачу во время выполнения таким же образом, что бы без дженериков:
class Test {
private List<String> myList;
public void setList(List<String> list) {
myList = list;
}
public void showLengths() {
for (String s : myList) {
System.out.println(s.length());
}
}
}
...
List<Integer> doesNotWork = new ArrayList<Integer>();
doesNotWork.add(1);
doesNotWork.add(2);
doesNotWork.add(3);
Test tst = new Test();
tst.setList(doesNotWork); // <<== Will not compile
Method setList = Test.class.getMethod("setList", List.class);
setList.invoke(tst, doesNotWork); // <<== This will work;
tst.showLengths(); // <<== However, this will produce a class cast exception
Demo on ideone.
* См this answer подробную информацию о получении информации, связанной с общими типами во время выполнения.
Во время компиляции, но после проверки. –
Очевидно, что информация не удаляется до того, как компилятор будет создан с использованием информации. –
Компилятор ничего не удаляет из вашего файла '.java', вместо этого он создает файл' .class' и не копирует комментарии, импорт или всю общую информацию (некоторые из них все еще существуют). Поскольку вы начинаете с нуля , вы не сможете их удалить. –