Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Скачать 1.93 Mb.
|
Что такое «сериализация»?Сериализация (Serialization) - процесс преобразования структуры данных в линейную последовательность байтов для дальнейшей передачи или сохранения. Сериализованные объекты можно затем восстановить (десериализовать). В Java, согласно спецификации Java Object Serialization существует два стандартных способа сериализации: стандартная сериализация, через использование интерфейса java.io.Serializable и «расширенная» сериализация - java.io.Externalizable. Сериализация позволяет в определенных пределах изменять класс. Вот наиболее важные изменения, с которыми спецификация Java Object Serialization может справляться автоматически: добавление в класс новых полей; изменение полей из статических в нестатические; изменение полей из транзитных в нетранзитные. Обратные изменения (из нестатических полей в статические и из нетранзитных в транзитные) или удаление полей требуют определенной дополнительной обработки в зависимости от того, какая степень обратной совместимости необходима. к оглавлению Опишите процесс сериализации/десериализации с использованием Serializable.При использовании Serializable применяется алгоритм сериализации, который с помощью рефлексии (Reflection API) выполняет: запись в поток метаданных о классе, ассоциированном с объектом (имя класса, идентификатор SerialVersionUID, идентификаторы полей класса); рекурсивную запись в поток описания суперклассов до класса java.lang.Object (не включительно); запись примитивных значений полей сериализуемого экземпляра, начиная с полей самого верхнего суперкласса; рекурсивную запись объектов, которые являются полями сериализуемого объекта. При этом ранее сериализованные объекты повторно не сериализуются, что позволяет алгоритму корректно работать с циклическими ссылками. Для выполнения десериализации под объект выделяется память, после чего его поля заполняются значениями из потока. Конструктор объекта при этом не вызывается. Однако при десериализации будет вызван конструктор без параметров родительского несериализуемого класса, а его отсутствие повлечёт ошибку десериализации. к оглавлению Как изменить стандартное поведение сериализации/десериализации?Реализовать интерфейс java.io.Externalizable, который позволяет применение пользовательской логики сериализации. Способ сериализации и десериализации описывается в методах writeExternal() и readExternal(). Во время десериализации вызывается конструктор без параметров, а потом уже на созданном объекте вызывается метод readExternal. Если у сериализуемого объекта реализован один из следующих методов, то механизм сериализации будет использовать его, а не метод по умолчанию : writeObject() - запись объекта в поток; readObject() - чтение объекта из потока; writeReplace() - позволяет заменить себя экземпляром другого класса перед записью; readResolve() - позволяет заменить на себя другой объект после чтения. к оглавлению Как исключить поля из сериализации?Для управления сериализацией при определении полей можно использовать ключевое слово transient, таким образом исключив поля из общего процесса сериализации. к оглавлению Что обозначает ключевое слово transient?Поля класса, помеченные модификатором transient, не сериализуются. Обычно в таких полях хранится промежуточное состояние объекта, которое, к примеру, проще вычислить. Другой пример такого поля - ссылка на экземпляр объекта, который не требует сериализации или не может быть сериализован. к оглавлению Какое влияние оказывают на сериализуемость модификаторы полей static и finalПри стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками. Поля с модификатором final сериализуются как и обычные. За одним исключением – их невозможно десериализовать при использовании Externalizable, поскольку final поля должны быть инициализированы в конструкторе, а после этого в readExternal() изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final полем необходимо использовать только стандартную сериализацию. к оглавлению |