|
Навигация
|
Главная » Java Теория и практика Java: Использование возможностей языка Java 5 в предыдущих версиях JDK (исходники)Источник: IBM developerWorks Россия Брайан Гетц, главный консультант, Quiotix В версии Java 5 в язык было добавлено много значительных возможностей: generic'и, перечисляемые типы, аннотации, autoboxing, улучшенный цикл for. Однако многие группы разработки все еще привязаны к JDK 1.4 или более ранним версиям и могут находиться в таком состоянии еще некоторое время. Тем не менее эти разработчики все-таки могут использовать эти полезные возможности языка, продолжая устанавливать приложения на ранние версии JVM. Возвратившийся после перерыва Брайан Гетц в этой статье серии Теория и практика Java покажет, как этого добиться.После недавнего выхода Java 6.0 можно было бы подумать, что возможности Java 5 уже стали стандартом. Но даже сейчас, когда я спрашиваю программистов, какую версию платформы Java они используют для разработки, обычно только половина применяет Java 5, а другая половина им завидует. Многие хотели бы использовать возможности языка, добавленные в Java 5, такие как generic'и и аннотации, но в силу определенных причин не могут сделать этого. Одна из категорий разработчиков, которые не могут воспользоваться преимуществами функциональности Java 5, - это разработчики компонентов, библиотек и каркасов для разработки приложений. Дело в том, что их заказчики, возможно, все еще используют JDK 1.4 или более ранние версии, а классы, скомпилированные под Java 5, не могут быть загружены JDK 1.4 и более старыми JVM. Поэтому использование возможностей языка Java 5 может привести к сокращению круга их заказчиков, оставив им только компании, уже перешедшие на Java 5. Другая группа разработчиков, воздерживающаяся от использования Java 5, - это программисты, работающие с Java EE. Многие группы разработчиков не хотят использовать Java 5 c Java EE 1.4 и более ранними версиями из опасения, что Java 5 не будет поддерживаться производителем используемого ими сервера приложений. Так что пройдет некоторое время, прежде чем такие проекты начнут переходить на Java 5. Также, кроме временного разрыва между спецификациями Java EE 5 и Java SE 5, не факт, что коммерческие контейнеры Java EE 5 появятся сразу же после выпуска новой версии спецификации. Компаниям вовсе не обязательно обновлять свои сервера приложений сразу после выхода новой версии, и даже после обновления сервера приложений может потребоваться время для сертификации приложений на новую платформу. Реализация возможностей языка в Java 5Возможности языка, добавленные в Java 5, - generic'и, перечисляемые типы, аннотации, autoboxing и улучшенный цикл for- не требуют изменений в наборе инструкций JVM и практически полностью реализованы в статическом компилятореjavac и библиотеках классов. Когда компилятор обнаруживает использование generic'ов, он пытается проверить, что обеспечивается безопасность типов, выдавая предупреждение "unchecked cast" (непроверенное преобразование), если не может это проверить, а затем генерирует байт код, полностью идентичный байт-коду, полученному из эквивалентного не-generic кода с преобразованиями и т.д. Точно также autoboxing и улучшенный цикл for - это просто "синтаксическая лафа" для совершенно эквивалентного, но более длинного кода, а перечисляемые типы компилируются в обычные классы.В теории можно взять классы, сгенерированные javac , и загрузить их в более раннюю JVM. На самом деле это и было целью создания группы JSR 14, группы Java Community Process, отвечающей за generic'и. Однако другие проблемы (такие как сохранение аннотаций), заставили изменить версию файла класса в Java 5 по сравнению с Java 1.4, что не позволяет загружать код, скомпилированный для Java 5, в более ранние версии JVM. Также некоторые из возможностей языка, добавленные в Java 5, зависят от библиотек Java 5. Если откомпилировать класс командой javac -target 1.5 и попытаться загрузить его в более раннюю JVM, возникнет ошибка UnsupportedClassVersionError , так как параметр -target 1.5 генерирует классы с версией файла класса равной 49, а JDK 1.4 поддерживает только версии файлов классов до 48.Цикл for-eachУлучшенный циклfor , иногда называемый циклом for-each , обрабатывается компилятором так, как если бы программист предоставил аналогичный цикл for в старом стиле. Цикл for-each позволяет осуществлять итерацию по элементам массива или коллекции. В примере 1 приведен синтаксис итерации по коллекции с помощью цикла for-each .Пример 1. Цикл for-each
Компилятор превратит этот код в аналогичный цикл, использующий итераторы, как показано в примере 2. Пример 2. Эквивалент кода в примере 1 с использованием итераторов
Каким образом компилятор определяет, что у предоставленного аргумента есть метод iteraror() ? Архитекторы компилятора javac могли бы встроить в него понимание framework'a для работы с коллекциями, но этот подход мог привести к ненужным ограничениям. Вместо этого был создан новый интерфейс java.lang.Iterable (см. пример 3), а классы коллекций были модифицированы так, чтобы реализовывать Iterable . В результате классы-контейнеры, даже не построенные на базовых коллекциях из framework'a, также могут использовать возможности нового цикла for-each . Но это создает зависимость от библиотеки классов Java 5, так как интерфейс Iterable отсутствует в библиотеке JDK 1.4.Пример 3. Интерфейс Iterable
Перечисляемые типы и autoboxingТакже как и циклfor-each , перечисляемые типы требуют поддержки библиотеки классов. Когда компилятор встречает перечисляемый тип, он генерирует класс, наследующий библиотечному классу java.lang.Enum . Но также как и Iterable , класс Enum отсутствует в библиотеке классов JDK 1.4.Аналогично autoboxing использует методы valueOf() , добавленные в классы-оболочки для примитивных типов, такие как Integer . Если boxing требует преобразования из int в Integer , то вместо вызова new Integer(int) компилятор генерирует вызов Integer.valueOf(int) . Эта реализация метода valueOf() использует шаблон flyweight для кэширования объектов Integer для часто используемых целых значений типа integer. Например, реализация Java 6 кэширует integer значения от -128 до 127, что позволяет производительность за счет устранения избыточного создания объектов. При этом, как и в случае Iterable и Enum , метод valueOf() отсутствует в библиотеке классов JDK 1.4.Varargs (методы с переменным числом аргументов)Когда компилятор встречает метод, определенный со списком параметров переменной длины, он преобразует его в метод, который принимает массив компонентов соответствующего типа. Когда компилятор встречает вызов метода со списком параметров переменной длины, то он упаковывает эти элементы в массив.АннотацииПри определении аннотации она может быть объявлена с аннотацией@Retention , которая указывает, как компилятор должен поступать с классами, методами или полями, которые используют эту аннотацию. Предусмотренные политики сохранения - SOURCE (отбрасывать данные из аннотации при компиляции), CLASS (записывать аннотации в файл класса), RUNTIME (записывать аннотации в файл класса и сохранять их во время исполнения, чтобы к ним можно было обращаться рефлексивным образом).Другие зависимости от библиотекДо Java 5, когда компилятор встречал попытку сложить две строки, он использовал вспомогательный классStringBuffer , чтобы выполнить сложение. В Java 5 и более поздних версиях вместо этого он генерирует вызовы к новому классу StringBuilder , который не представлен в JDK 1.4 и более ранних библиотеках классов.Использование возможностей Java 5Из-за зависимости возможностей языка от библиотек поддержки даже если class-файлы, созданные компилятором Java 5, удастся загрузить в предыдущую версию JVM, то исполнить их все равно не получится из-за ошибок при загрузке классов. Однако подобные проблемы можно решить соответствующим преобразованием байт-кода, так как недостающие классы не содержат важной функциональности.JSR 14Во время разработки спецификации Java generic'ов и других возможностей языка Java, добавленных в Java 5, в компиляторjavac была добавлена экспериментальная поддержка, позволяющая ему использовать возможности языка Java 5 и генерировать байт-код, который можно запускать на JVM 1.4. Хотя эти возможности официально не поддерживаются и даже не задокументированы, они используются в ряде проектов Open Source, чтобы позволить разработчикам использовать языковые возможности Java 5 и создавать JAR-файлы, работающие на более ранних JVM. Теперь, когда javac стал Open Source-проектом, эти возможности могут поддерживаться сторонними разработчиками. Чтобы активировать эти возможности, можно запустить javac с параметрами -source 1.5 и -target jsr14 .Режим JSR 14 заставляет компилятор javac генерировать JDK 1.4-совместимый байт-код, обладающий возможностями Java 5.
RetroweaverВ Java 5 есть языковые возможности, не поддерживаемые режимом JSR 14, например, такие какIterable и перечисляемые типы. Альтернативный подход, применяемый в таких Open Source-проектах, как Retroweaver и Retrotranslator, предлагает генерировать байт-код, используя параметр -target 1.5 , и затем механически преобразовывать байт-код в формат, совместимый с JDK 1.4Первой появилась утилита Retroweaver, которая обрабатывает все случаи, обрабатываемые javac -target JSR 14, а также предоставляет еще несколько возможностей.
RetrotranslatorКак это часто случается в Open Source-сообществе, если проект перестает двигаться вперед, он объявляется "мертвым", и его место занимает новый проект, даже если первый проект только решил "отдохнуть". Именно такая история произошла с Retroweaver - основной разработчик проекта решил отдохнуть от него, и его место занял другой аналогичный проект - Retrotranslator. Retrotranslator предлагает такие же возможности, как Retroweaver, и еще много дополнительных возможностей, направленных на поддержку важных обновлений в библиотеке классов Java 5.
ЗаключениеУ тех невезучих разработчиков, которые не могут использовать новые возможности Java 5, - а таких разработчиков, к сожалению, еще очень много, - есть несколько путей, позволяющих им использовать новые возможности и сохранить совместимость байт-кода с JDK 1.4 и более старыми версиями. Имеется неподдерживаемая опция-target jsr14 компилятора javac , позволяющая генерировать JDK 1.4-совместимый байт-код для некоторых возможностей Java 5, а также Open Source-проекты Retroweaver и Retrotranslator, преобразующие большинство байт-кода Java 5 в Java 1.4-совместимый байт-код. Что бы вы ни выбрали, не забудьте выполнить тестирование с особой тщательностью, чтобы убедиться в полной совместимости.Очаровательный Python: Изящество и неловкость Python. Часть 2 (исходники). Практически Groovy: Подмешайте немного Groovy в приложения Java (исходники). Компания Interface Ltd. начала поставки Crystal Reports XI. EJB Advocate: EJB 2.x умерла? (исходники). Статистическое программирование на R: Часть 3. Повторное использование кода и объектное программирование (исходники). Главная » Java |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |