Тимур Машнин – Графические интерфейсы пользователя Java (страница 11)
Сюда входят примитивные типы, массивы и строки.
API не сериализует или десериализует поля, отмеченные как transient или static.
Transient (нерезидент) – модификатор полей класса.
Отмеченные этим модификатором поля не записываются в поток байт при применении стандартного алгоритма сериализации.
При десериализации объекта такие поля инициализируются значением по умолчанию.
Этот модификатор применяется, например, если поле класса является объектом несериализуемого класса, или некоторые поля могут не сериализоваться из соображений безопасности, например, поле пароля, или значение поля корректно только в рамках текущего контекста.
Вы можете контролировать уровень сериализации объекта.
Есть несколько способов управления серилизацией:
Это автоматическая сериализация, реализуемая интерфейсом Serializable.
Программное обеспечение сериализации Java сериализует весь объект, за исключением полей transient или static.
Интерфейс Serializable не объявляет никаких методов; он действует как маркер, сообщая инструментам сериализации объектов, что ваш класс сериализуется.
Маркировка класса интерфейсом Serializable означает, что вы сообщаете виртуальной машине Java (JVM), что ваш класс будет работать с сериализацией по умолчанию.
Классы, которые реализуют Serializable, должны иметь доступ к конструктору без аргументов супертипа.
Этот конструктор будет вызываться, когда объект будет «восстанавливаться» из файла. ser, в котором хранится сериализованный объект.
Вам не нужно реализовывать Serializable в вашем классе, если он уже реализован в суперклассе.
Все поля, кроме полей transient или static, сериализуются.
Используйте модификатор transient, чтобы указать поля, которые вы не хотите сериализовать, и указать классы, которые не являются сериализуемыми.
Если объект однажды уже записанный в поток, спустя какое-то время записывается в него снова, то по умолчанию, ObjectOutputStream сохраняет ссылки на объекты, которые в него записываются.
Это означает, что, если состояние записываемого объекта, который уже был записан, будет записано снова, новое состояние не сохраняется.
Существует два способа это исправить.
Во-первых, вы можете каждый раз после вызова метода записи закрывать поток, а затем открывать его снова.
Во-вторых, вы можете вызвать метод ObjectOutputStream.reset, который сигнализирует потоку о том, что необходимо освободить кэш от ссылок, которые он хранит, чтобы новые вызовы методов записи действительно записывали данные.
Вы можете дополнительно контролировать, как объекты сериализуются, путем написания собственных реализаций методов writeObject и readObject и включить их в свой сериализуемый класс.
Классы, требующие специальной обработки во время процесса сериализации и десериализации, должны определить эти методы с этими точными сигнатурами.
Метод writeObject класса определяет сериализацию объекта.
А метод readObject восстанавливает поток данных, который вы определили с помощью writeObject.
Если же вы хотите полностью контролировать сериализацию объекта, используйте интерфейс Externalizable, например, при записи и чтении определенного формата файла.
Для использования интерфейса Externalizable вам необходимо реализовать два метода: readExternal и writeExternal.
Классы, которые реализуют Externalizable, должны иметь конструктор без аргументов.
Класс XMLEncoder позволяет сериализовать объект в XML-файл.
Одно из достоинств этой формы сериализации заключается в том, что вы можете легко просмотреть данные объекта в сохраненной форме.
Вы также можете изменить данные в файле в текстовом редакторе.
Соответственно с помощью класса XMLEncoder, можно легко восстановить потом объект из XML-файла.
Библиотека Swing
Графическая библиотека Swing была создана на основе библиотеки AWT для решения таких проблем AWT как недостаточный выбор графических компонентов и зависимость внешнего вида и поведения AWT графического интерфейса пользователя от конкретной операционной системы.
Эти проблемы были решены созданием классов и интерфейсов библиотеки Swing с использованием одного только языка Java.
Компоненты AWT являются тяжеловесными, в то время как компоненты Swing являются легковесными.
Библиотека AWT использует нативный код (код, специфичный для конкретной операционной системы) для отображения компонентов.
Каждая реализация среды выполнения Jave Runtime Environment должна обеспечивать собственные реализации кнопок, меток, панелей и всех других компонентов AWT.
Всякий раз, когда используется компонент AWT, все запросы на рисование пересылаются нативному коду.
Это позволяет использовать кнопку AWT в приложении, но кнопка отображается как кнопка Windows, или кнопка Mac или другая кнопка конкретной платформы, на которой работает приложение.
Эти части нативного кода, к которым обращается среда выполнения JRE при использовании AWT компонентов, называются пирами, так как они берут на себя ответственность за отображение компонента.
Прежде чем AWT компонент будет сначала нарисован на экране, будет создан его пир.
Код пира включает в себя нативный код для отображения компонента, определения текущего размера экрана и решения других проблем с нативной платформой.
Например, когда Java рисует метку, она не просто рисует строку в нужном месте на экране.
Она создает пир и помещает его на экран.
В свою очередь компоненты Swing используют пиры для двух задач.
Во-первых, Swing компоненты JFrame, JWindow, JDialog и JApplet расширяют свои AWT-аналоги.
И все они используют пиры для отображения фактической области рисования на экране.
Другие компоненты Swing легковесные; у них нет пиров.
Эти компоненты отрисовывают себя поверх существующих JFrame, JWindow, JDialog или JApplet.
И поэтому на самом деле они также неявно используют пиры.
В AWT библиотеке использование пиров значительно затрудняло создавать подклассы этих компонентов для изменения их поведения.
Потому что их поведение исходит от нативного пира и поэтому не может быть легко переопределено или расширено.
Далее, наличие нативного кода значительно затрудняет перенос Java на новую платформу.
Проще говоря, хотя сам язык Java был кросс-платформенным, библиотека AWT была его ахиллесовой пятой.
Наконец, нативные пиры потребляют много ресурсов.
Можно было бы ожидать, что использование нативного кода будет намного более эффективным, чем создание компонентов на Java.
Тем не менее, для создания большого количества элементов GUI может потребоваться много времени, когда для каждого из них требуется создание его пира.
Решением было создание легковесных компонентов библиотеки Swing, которые полностью написаны на Java, и поэтому не требуют прямого использования нативного кода.
Легковесный компонент – это просто компонент, полностью реализованный на Java.
Для создания легковесного компонента достаточно расширить AWT класс Component или Container напрямую, реализуя внешний вид компонента на Java, а не делегируя внешний вид пиру.
Легковесные компоненты могут быть прозрачными, и они не должны быть прямоугольными, что является ограничением при работе с компонентами, имеющими пиры.
Вы реализуете весь внешний вид, используя методы paint и update, и вы реализуете поведение компонента, улавливая пользовательские события и, возможно, генерируя новые события.
В библиотеке AWT для создания совершенно нового компонента вам нужно было бы расширять класс Canvas.