Java Development Kit из компании Sun Microsystems с завидным постоянством нарушают эту традицию. Так, разница между версиями JDK 1.0 и 1.1 просто огромная. То же можно сказать и о различиях между JDK 1.1 и только что появившимся вариантом JDK 1.2.
Безопасность данных
В пакете JDK 1.2 модель безопасности данных значительно изменена за счет применения политики защиты данных (policy). Коду класса при загрузке присваиваются права доступа согласно политике защиты данных, действующей в этот момент. Права доступа к ресурсам разнообразны: любую операцию с файлами можно разрешить или запретить, изменяя политику защиты. Предусмотрено присвоение отдельных разрешений коду, полученному из определенного адреса сети или имеющему цифровую подпись. Скажем, вы разрешаете доступ к диску на вашей рабочей станции любому коду, запущенному с компьютера коллеги. Такую же возможность можно предоставить аплету некой фирмы, если цифровая подпись будет соответствовать оригинальной.
Новая концепция защиты данных пригодна применительно не только к аплетам, но и к приложениям любого рода, а также к компонентам JavaBeans и сервлетам*.
В JDK 1.2 предлагаются три новых инструмента:
- keytool - генерирует ключи (public/private) показа, импорта и экспорта сертификатов, а также сами сертификаты X.509 v1;
- jarsigner - "подписывает" архивы в формате JAR и проверяет аутентичность подписей JAR-файлов;
- policytool - создает и изменяет файлы определения политики.
Java Foundation Classes
В папке под названием Java Foundation Classes (JFC) собрано несколько библиотек, каждая из которых играет значительную роль. С одной из них - библиотекой пользовательского интерфейса Swing - мы вас знакомили (начиная с № 9/98, с. 182). Все классы Swing выполнены как "легковесные", т. е. не обращающиеся к аналогичным компонентам операционной системы. Это позволяет одинаково отображать один и тот же компонент в разных операционных средах. Все компоненты Swing соответствуют стандарту Pure Java, и при этом они более функциональны, чем их "собратья", встроенные в пользовательский интерфейс операционных систем. К тому же в библиотеке Swing найдутся и такие компоненты, аналогов которым нет.
Не менее полезным окажется и новый программный интерфейс Java 2D, призванный дополнить уже имеющийся графический интерфейс awt. Здесь и встроенная поддержка буферизации изображений, и сложные операции с изображениями, и задание прозрачности с помощью альфа-канала, а кроме того, масса операций по точному заданию цветов, шрифтов, афинных преобразований и т. д. Расширения столь значительны, что им отводится более 120 страниц в документации.
В новой версии JFC появился специальный программный интерфейс Java Accessibility, реализующий чтение голосом с экрана, распознавание речи, управление терминалами Брайля. Такие средства могут быть полезны не только для людей с ослабленным зрением.
Частью JFC являются также перетаскивание данных и несколько служб приложений (Application Services):
- клавиатурная навигация - делает возможным преобразование определенных клавишных комбинаций в события мыши, что эквивалентно использованию мыши в управлении (заданной комбинацией клавиш можно эмулировать выбор пункта меню или нажатие кнопки в диалоговой панели);
- многопоточная очередь сообщений - расширяет стандартную очередь, делая удобным получение сообщений от разных потоков и давая возможность управлять пользовательским интерфейсом из отдельного потока;
- Undo/Redo - представляет сервисы по организации отмены и возврата ранее выполненных команд и изменений;
- модель ограниченного диапазона - устанавливает ограничения на значения;
- настраиваемые курсоры мыши - курсоры могут быть определены разработчиком на основе произвольного изображения; "горячее пятно" также может быть определено;
- утилита отладки графики - инструмент, поэтапно показывающий процесс рисования частей визуальных компонентов; полезен при создании собственных компонентов;
- групповое рисование - механизм оптимизации одновременного рисования группы областей экрана.
Коллекции
Разработчиками первых версий JDK многое было упущено. Особенно был заметен пробел в области классов для хранения данных. Программистам приходилось довольствоваться вектором (Vector) и хэш-таблицей (hash table) или обращаться к сторонним библиотекам, например к JGL компании ObjectSpace.
Новая версия JDK 1.2 ситуацию радикально меняет. Теперь в пакете java.util находятся 25 классов для работы с различными данными. Кроме того, в новых коллекциях присутствуют средства синхронизации доступа к данным и возможность запретить изменения и редактирование хранимых данных.
Определенные сдвиги произошли и в общем (generic) программировании. Тем, кто применяет в своей работе язык Cи++, общее программирование знакомо по библиотеке STL. Новые средства JDK 1.2 обеспечат хранение и обработку данных любого типа одними и теми же вспомогательными классами.
Дополнения к JavaBeans
Модель компонентов JavaBeans, применяемая в JDK 1.2, носит название Glasgow. Данная модель сподвигает программиста писать более эффективные компоненты JavaBeans и приложения, нежели те, что изготавливаются в настоящее время. Применение Glasgow сулит более тесную интеграцию Java-классов в их "среду обитания", т. е. "рабочий стол", браузер, операционную систему (если последняя позволяет). С этой целью в Glasgow добавлены:
- специальный служебный протокол и контекст компонента;
- средства перетаскивания;
- средства активизации (JavaBeans activation framework).
Пока еще рано говорить о Glasgow как о завершенном проекте. Разработка и модификация продолжаются.
Изменения в RMI
Изменения коснулись и технологии RMI (Remote Method Invocation), часто используемой для организации распределенных вычислений. По примеру компонентной объектной модели Microsoft в RMI добавлены долгоживущие (persistent) ссылки на удаленные объекты - по ним можно обращаться к объекту даже в том случае, если в памяти компьютера нет ни одного экземпляра этого объекта. Кроме того, благодаря применению специализированных фабрик сокетов (custom socket factories) стала возможной поддержка различных протоколов для вызова объектов.
Из мелких усовершенствований полезными окажутся отмена экспорта удаленного объекта (unexporting a remote object), получение заглушки (stub) для реализации объекта (object implementation), реализация локального объекта по заглушке и экспорт объекта на определенном порту.
Дополнения к сериализации объектов
Для сохранения и восстановления состояния объектов, особенно компонентов JavaBeans в Java, достаточно широко используется сериализация. В JDK 1.2 сериализация расширена новыми методами управления процессом сохранения и восстановления данных. Прежде всего отметим появление интерфейсов ObjectOutputStream.PutField и ObjectOutput Stream.GetField, предоставляющих доступ к сериализуемым полям, которые описаны внутри несериализуемого класса. Если потребуются более тонкие инструменты для сериализации, можно воспользоваться двумя новыми методами writeReplace и readResolve, сходными с writeObject и readObject. При сериализации сначала ищутся методы writeReplace и readResolve, и только после того как они не найдены, за дело принимаются writeObject и readObject.
В JDK 1.2 появились новый протокол сериализации и возможность управлять его подключением. По умолчанию JDK 1.2 использует запись в новом формате, что может вызвать проблемы совместимости с предыдущими версиями JDK. Избежать этого просто - нужно установить версию протокола сериализации методом ObjectOutput Stream.useProtocolVersion.
Изменения коснулись не только кода, но даже средств документирования сериализации. Утилита javadoc расширена тегами @serial, @serialField и @serialData, и стандартный доклет утилиты javadoc генерирует документацию по отмеченным ими полям.
Использование доклетов - сравнительно новая доктрина функционального расширения утилиты генерации документации javadoc. Доклет - это программа, написанная с применением специального программного интерфейса. Применение доклетов открывает дополнительные возможности по форматированию документации. Можно написать доклет, который будет генерировать файлы не только формата HTML, принятого сейчас в качестве основного формата хранения документов, но и таких файловых форматов, как SGML, XML и RTF.
Ссылочные объекты
Ссылочные объекты - новый вид классов, поддерживающих простейшее взаимодействие со сборщиком мусора. Любая Java-программа может использовать ссылочные объекты как обычные ссылки, но при этом объекты, на которые эти ссылки установлены, утилизуются сборщиком мусора в любое время.
Ссылочные объекты незаменимы для создания временных хранилищ данных в оперативной памяти. Хорошим примером служит кэшируемый блок записей из базы данных, выбранных из дискового хранилища и сохраненных в памяти. Если виртуальная машина Java обнаруживает нехватку свободной оперативной памяти, она обращается к сборщику мусора, и тот начинает очищать сначала те участки оперативной памяти, в которых хранятся уже удаленные объекты, а затем чистит блоки, на которые имеются ссылочные объекты. Так, блок с кэш-выборкой данных может быть очищен безболезненно - данные можно снова считать с диска.
Java Sound
Пакет JDK 1.2 получил от разработчиков новый звуковой "движок", что позволяет приложениям работать со звуком наравне с аплетами. Поддерживаются три формата аудиофайлов (AIFF, AU и WAV) и три разновидности MIDI-файлов (MIDI TYPE 0, MIDI TYPE 1 и RMF). Все звуки могут быть 8- и 16-разрядными с частотой выборки от 8 до 48 кГц и записаны как в моно-, так и в стереоформате.
Программный MIDI-синтезатор основан на волновых таблицах и может обслуживать до 64 каналов цифрового и MIDI-звука. По умолчанию 16-разрядный звук воспроизводится в стереоварианте с частотой дискретизации 22 кГц. Если клиентская сторона не обладает подходящими возможностями, режим воспроизведения переключается на 8-разрядный монорежим.
Для реализации звуковой поддержки в приложениях можно применять новый метод:
public static final AudioClip newAudioClip(URL url)
Java IDL
Компилятор Java IDL привносит в JDK 1.2 элементы технологии CORBA, с помощью которой реализуются распределенные системы стандарта OMG IDL. Компоненты времени исполнения содержат полноценный брокер объектных запросов (ORB), поддерживающий протокол IIOP.
Однако по всей видимости Java IDL будет поставляться отдельно от JDK 1.2.
Расширения
Расширения (extensions) - это пакеты классов (и связанного с ними "родного" кода), применяемые для увеличения функциональных возможностей базовой платформы Java. Запустить расширение невероятно просто - достаточно переписать архив (JAR) с расширениями в каталог jrelibext среды выполнения Java. Виртуальная машина Java "подберет" расширяющие классы оттуда. По желанию они могут быть выполнены как загружаемые и в этом случае будут динамически подгружаться из указанного места сети.
Улучшение архивов JAR
Архивы JAR, способные вмещать аплеты, компоненты и прочие объекты, широко применяются на самых различных платформах. Их возможности значительно расширены за счет новых директив файлов манифеста. Для чтения и записи JAR-архивов появился новый программный интерфейс, а новый механизм расширений Java предоставляет средства для слежения за взаимными ссылками различных архивов.
На пользовательском уровне изменения не столь значительны, но весьма полезны. Так, в архиваторе JAR появились две опции командной строки. Одна из них (u) добавляет файл, если его нет в архиве, или обновляет экземпляр файла, уже находящийся в архиве. Другая полезная опция (С) позволяет задавать текущий каталог, откуда JAR берет файлы для архивации. Опция C пригодится при упаковке файлов, расположенных в различных ветвях дерева файловой системы. Ранее для такого рода операций приходилось копировать архивируемые файлы в отдельный каталог и уже оттуда формировать архив, что не очень-то удобно.
Методы отражения
Отражение (reflection) применяется для получения информации о полях, методах и конструкторах, загруженных в оперативную память классов, и динамического доступа к ним. Улучшенные в JDK 1.2 методы отражения позволяют обходить контроль доступа к классам, но лишь в тех случаях, когда для обращения к классам используется интерфейс отражения. Классы Field, Method и Constructor содержат специальный метод setAccessible, управляющий доступом через отражение.
JDBC 2.0
Интерфейс доступа к данным JDBC не сделала популярным даже относительная простота, так как скорость его работы была невелика. Однако новая версия JDBC 2.0, представленная на очередном шоу JavaOne'98, продемонстрировала убедительные улучшения. Появились курсоры, работающие при проверке результирующих выборок и сочетающие перемещение с модификацией данных в элементах выборки.
JDBC 2.0 поддерживает данные типов BLOB (большие бинарные объекты), CLOB (большие символьные объекты) и пользовательские (UDT).
Увеличение производительности
Чтобы поднять производительность, в JDK 1.2 сделаны несколько улучшений:
- добавлена поддержка "родных" потоков Solaris - в многопроцессорных системах выполнение "родных" потоков может планироваться на разных процесорах;
- реже используется память загруженными классами - для этого строчные константы делаются общедоступными для нескольких классов сразу;
- ускорены выделение и очистка памяти - у потоков появился собственный локальный кэш, что устраняет дорогостоящие операции выделения и очистки памяти;
- ускорены мониторы синхронизации - все тот же локальный кэш позволяет обращаться к мониторам синхронизации со скоростью, близкой к скорости выполнения обычных методов;
- оптимизированы важные классы - многие базовые классы Java переписаны с использованием "родных" методов;
- компилятор Just In Time - как в старые добрые времена, выполнение приложений "подгоняет" JIT-компилятор.
Интерфейсы инструментальной поддержки
Для взаимодействия с отладчиками и прочими инструментами разработки в пакете JDK 1.2 предусмотрен программный интерфейс Java Virtual Machine Debugger Interface (JVMDI), с помощью которого можно не только узнать о внутреннем состоянии объектов приложения, но и управлять его выполнением. Так что справедливо будет сказать, что JVMDI - интерфейс двусторонний. Клиентские программы, использующие JVMDI, выполняются на той же виртуальной машине Java, что и отлаживаемое приложение.
Интерфейс JVMDI - это лишь один слой в отладочной архитектуре Jbug, содержащей высокоуровневые интерфейсы для отладки, вызываемые из отдельных процессов. В паре с ним работает другой интерфейс - Java Virtual Machine Profiler Interface (JVMPI), предназначенный для создания профиля программы (пока еще не является стандартным интерфейсом и продолжает развиваться). Это тоже двусторонний интерфейс, позволяющий не только получать сообщения при изменении свойств программы, но и управлять процессом формирования профиля.
Настройка среды выполнения
Вот и случилось то, чего ожидали многие программисты. Теперь настроечные файлы переменной среды CLASSPATH, которая часто может растягиваться на несколько строк, не будут неоправданно загромождать оперативную память и создавать массу проблем с настройкой среды выполнения. Все системные классы автоматически обнаруживаются виртуальной машиной и подгружаются в оперативную память по мере надобности. Текущее местоположение этих классов можно узнать, считав свойство sun.boot.class.path. При необходимости можно указать альтернативный каталог поиска библиотечных классов, определив в командной строке запуска виртуальной машины опцию Xbootclasspath:путь/файлы.
Кстати, не ищите в библиотечном каталоге привычный файл classes.zip, его там нет. Вместо него вы найдете три архива в формате JAR: rt.jar, i18n.jar и jaws.jar. Отсюда виртуальная машина Java и считывает образы системных классов. n
Подробнее с возможностями нового пакета JDK 1.2 можно познакомиться по документации и многочисленным примерам на Web-узле http://www.javasoft.com.
* Сервлеты - небольшие программы, исполняемые на сервере. Расширяют функциональность последнего.