Я понимаю, что генерические файлы проверяются во время компиляции и что это предотвращает исключения во время выполнения, не позволяя компилировать код с неисправными генериками. При компиляции компилятор после подтверждения того, что генерики были правильно реализованы, преобразует родовые типы в необработанные типы. Зачем? Я безуспешно пытаюсь понять, в чем преимущество этого преобразования. У кого-нибудь есть объяснение?Почему компилятор конвертирует общие типы в необработанные типы?
ответ
Поскольку дженерики не были частью Java с самого начала (1.0). Если бы это было так, это было бы реализовано с использованием Reification. Цитирование Брюс Eckel на «Мышления в Java»:
В действительности, даже если программисты пишут только общий код, они будут иметь дело с необщей библиотекой, которые были написаны до Java SE5. У авторов этих библиотек никогда не может быть стимула генерировать свой код, или они могут просто потратить время на то, чтобы добраться до него. Таким образом, Java-генераторы не только должны поддерживать обратную совместимость. Существующие файлы кода и классов по-прежнему являются законными и продолжают означать, что они имели в виду до этого, но также должны поддерживать совместимость с миграцией, чтобы библиотеки могли стать универсальными в своем собственном темпе и когда библиотека становится универсальной, она не нарушает код и приложения, которые зависят от него. Поняв, что это была цель, разработчики Java и различные группы, работающие над проблемой, решили, что стирание является единственным возможным решением. Erasure позволяет эту миграцию в отношении дженериков, разрешая совместное существование не общего кода с общим кодом.
Как вы можете прочитать на http://www.artima.com/intv/generics2.html Первоначальная цель генерации Java была выполнена на немодифицированной виртуальной машине. Вот почему генераторы обрабатываются компилятором.
Реализация дженериков Java была основана на проекте, первоначально названном Pizza, который был сделан Мартином Одерским и другими. Пицца была переименована в GJ, затем она превратилась в JSR и в итоге была переведена на язык Java. И это конкретное предложение дженериков имело в качестве ключевой цели дизайна, что оно могло работать на немодифицированной виртуальной машине [Virtual Machine]. Разумеется, здорово, что вам не нужно изменять вашу виртуальную машину, но она также создает целую кучу странных ограничений. Ограничения не обязательно очевидны, но вы очень быстро идете: «Хм, это странно».
Вы должны прочитать о тире Erasure и о том, как он относится к сырым типам. Рассмотрим следующий код:
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello"); // Causes a ClassCastException to be thrown.
Integer x = mn.data;
После типа стирания, этот код становится:
MyNode mn = new MyNode(5);
Node n = (MyNode)mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
Вот что происходит, когда код выполняется:
n.setData (» Здравствуйте"); вызывает метод setData (Object), который должен быть выполнен на объекте класса MyNode. (Класс MyNode унаследовал SetData (Object) от узла.)
В теле SetData (Object), поле данных объекта, на который ссылается п присваивается String.
Поле данных того же объекта, который ссылается через млн, может быть доступны и, как ожидается, быть целым числом (поскольку млн является MyNode, который является узлом.
Попытка назначить строку целым Integer вызывает ClassCastException из приведения, вставленного при назначении компилятором Java.
вы можете прочитать о типе Erasure здесь: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
- 1. Почему не компилятор решить эти общие типы
- 2. Общие типы, компилятор и динамические языки
- 3. Почему Java генерирует общие типы?
- 4. Необработанные типы и производительность
- 5. Rails: почему update_attribute автоматически конвертирует типы
- 6. Почему C# не выводит мои общие типы?
- 7. Встроенные общие типы
- 8. Java - общие типы
- 9. Несовместимые общие типы
- 10. Составляющие общие типы в Java
- 11. .NET SOAP Общие типы
- 12. Рекурсивные общие типы
- 13. Отражающие и общие типы
- 14. Structuremap и общие типы
- 15. Общие типы переменных типа?
- 16. Общие типы, не равные
- 17. Discover общие типы
- 18. vb.net сравнить общие типы
- 19. Общие типы, интерфейсы
- 20. Entity Framework общие типы
- 21. Общие типы (& T) в Rascal
- 22. Дополнительные общие типы
- 23. Общие типы java
- 24. Общие типы и LINQ
- 25. Общие типы крючков Subversion
- 26. NInject. Регистрировать общие типы
- 27. Как сравнить общие типы?
- 28. Почему компилятор сердится на изоморфные типы?
- 29. Почему параметры не принимают общие типы?
- 30. Почему общие типы не имеют явного макета?
Обратная совместимость. Старый код, который не использует generics, должен быть совместим с новым кодом, который делает, а старые JVM не понимают общий байт-код. – user2357112
@ user2357112 это правильно, отправьте его как ответ, а не комментарий. – Xabster
[Тип Erasure] (http://docs.oracle.com/javase/tutorial/java/generics/erasure.html) - «Заменить все параметры типа в родовых типах их границами или объектом, если параметры типа неограничены. Таким образом, созданный байт-код содержит только обычные классы, интерфейсы и методы ». –