Сериализация (Java)

Материал из Циклопедии
Перейти к навигации Перейти к поиску

Сериализация — это процесс сохранения состояния объекта в последовательность байт; десериализация это процесс восстановления объекта из этих байт. Используется как универсальный и эффективный протокол передачи объектов между компонентами Java.

Подходы к реализации[править]

Существует два способа организовать сериализацию класса:

Если реализовать оба подхода, будет применяться собственный алгоритм, определённый в реализации методов интерфейса Externalizable.

Стандартный алгоритм[править]

При использовании Serializable применяется стандартный алгоритм сериализации который с помощью рефлексии выполняет следующие действия:

  • запись в поток метаданных о классе, ассоциированном с объектом (имя класса, идентификатор SerialVersionUID, идентификаторы полей класса);
  • рекурсивная запись в поток описания суперклассов до класса java.lang.Object (не включительно);
  • запись примитивных значений полей сериализуемого экземпляра, начиная с полей с самого верхнего суперкласса;
  • рекурсивная запись объектов, которые являются полями сериализуемого объекта. При этом ранее сериализованные объекты повторно не сериализуются, что позволяет алгоритму коректно работать с циклическими ссылками.

При стандартной сериализации не сериализуются поля transient и static (кроме serialVersionUID — уникального идентификатора версии сериализованного класса, добавляемого на этапе компиляции к каждому классу, реализующему интерфейс Serializable).

При десериализации под объект выделяется память, после чего его поля заполняются значениями из потока. Конструктор объекта при этом не вызывается. Однако при десериализации вызовется конструктор без параметров родительского несериализуемого класса, а его отсутствие повлечёт ошибку десериализации.

Собственный алгоритм[править]

Если реализовать интерфейс Externalizable, будет вызвана пользовательская логика сериализации (в том числе если класс имплементит оба интерфейса). Способ сериализации и десериализации описывается в методах writeObject и readObject. При использовании же Externalizable во время десериализации вызывается конструктор без параметров, а потом уже на созданном объекте вызывается метод readExternal.

Собственный алгоритм сериализации может пригодится, например, при сериализации объекта, хранящего некоторый набор булевых значений. В этом случае вместо стандартной сериализации имеет смысл реализовать алгоритм, который будет группировать по восемь булевых значений в один байт, что позволит значительно уменьшить объём полученной последовательности байт.

Другой пример — сериализация секретных данных. В этом случае имеет смысл шифровать сериализуемые данные и дешифровать их при реализации, что требует собственной реализации алгоритма.

Ссылки[править]