Java предоставляет механизм, называемый сериализацией, для сохранения объектов Java в виде упорядоченных или последовательных байтов, которые включают данные объекта, а также информацию о типе объекта и типах данных, хранящихся в объекте.

Поэтому, если нам нужно сериализовать любой объект, его можно прочитать и десериализовать, используя тип объекта и другую информацию, чтобы мы могли получить исходный объект.

Классы ObjectInputStream и ObjectOutputStream - это потоки высокого уровня, которые содержат методы для сериализации и десериализации объекта.
ObjectOutputStream имеет много методов для сериализации объекта, но обычно используется метод

Аналогично ObjectInputStream имеет

Нужна сериализация в java?

Сериализация обычно используется, когда есть необходимость отправить данные по сети или сохранить в файлах. Под данными я имею в виду объекты, а не текст.

Теперь проблема в вашей сетевой инфраструктуре, а ваш жесткий диск - это аппаратные компоненты, которые понимают биты и байты, но не объекты Java.

Сериализация - это преобразование значений / состояний Java-объекта в байты для отправки по сети или для сохранения. С другой стороны, десериализация - это преобразование байтового кода в соответствующие java-объекты.

Концепция serialVersionUID:

serialVersionUID используется для того, чтобы гарантировать, что тот же класс (который использовался во время сериализации) был загружен во время десериализации. serialVersionUID используется для управления версиями объекта. Вы можете узнать больше в serialVersionUID в сериализации java

Для сериализации в java:
шаги:

Возьмем пример:
Создайте Employee.java в src- ›org.arpit.javapostsforlearning.

  1. Employee.java
As you can see above,if you want to serialize any class then it must implement Serializable interface which is marker interface. 
Marker interface in Java is interfaces with no field or methods or in simple word empty interface in java is called marker interface
Create SerializeMain.java in src->org.arpit.javapostsforlearning

2.SerializeMain.java

Для десериализации:

Шаги:

Создайте DeserializeMain.java в src- ›org.arpit.javapostsforlearning

3.DeserializeMain.java

4. запустить:

Сначала запустите SerializeMain.java, затем DeserializeMain.java, и вы получите следующий результат:

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS

Итак, мы сериализовали объект сотрудника, а затем десериализовали его. Это кажется очень простым, но может быть очень сложным, когда на картинке появляется ссылочный объект, наследование. Таким образом, мы увидим разные случаи один за другим и то, как мы можем применить сериализацию в разных сценариях .

Случай 1. Что делать, если объект имеет ссылку на другие объекты

Мы видели очень простой случай сериализации, теперь что, если это также ссылка на другие объекты.

Как тогда он будет сериализован? будет ли ссылочный объект также сериализован ?.

Да, вам не нужно явно сериализовать ссылочные объекты. Когда вы сериализуете какой-либо объект и если он содержит любую другую ссылку на объект, то сериализация Java сериализует весь граф этого объекта.

Например: Допустим, у Employee теперь есть ссылка на объект адреса, а Address может иметь ссылку на какой-либо другой объект (например, Home), тогда, когда вы сериализуете объект Employee, все другие ссылочные объекты, такие как адрес и дом, будут автоматически сериализованы. Давайте создадим класс Address и добавим объект Address в качестве ссылки на вышеуказанный класс сотрудников.

Employee.java:

Создайте Address.java в org.arpit.javapostsforlearning
Address.java:

Создайте SerializeDeserializeMain.java в org.arpit.javapostsforlearning

SerializeDeserializeMain.java:

Запустить:

Когда вы запустите SerializeDeserializeMain.java. Вы получите следующий вывод

java.io.NotSerializableException: org.arpit.javapostsforlearning.Address
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)

Мы получили исключение, что пошло не так. Я забыл упомянуть, что класс Address также должен быть сериализуемым, поэтому вам нужно сделать Address сериализуемым, реализовав сериализуемый интерфейс.

Address.java:

Выполнить еще раз:

Когда вы снова запустите SerializeDeserializeMain.java. Вы получите следующий результат

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS
City :Pune

Случай 2. Что делать, если у вас нет доступа к исходному коду ссылочного объекта (например, у вас нет доступа к указанному выше классу адресов)
Если у вас нет доступа к классу адресов тогда как вы реализуете сериализуемый интерфейс в классе Address. Есть ли альтернатива этому? да, есть, вы можете создать другой класс, который расширяет адрес и делает его сериализуемым, но во многих случаях это может дать сбой:

  • Что делать, если класс объявлен как final
  • Что делать, если у класса есть ссылка на другой несериализуемый объект.

Итак, как вы будете сериализовать объект Employee? Итак, решение в том, что вы можете сделать его временным. Если вы не хотите сериализовать какое-либо поле, сделайте его временным.

transient Address address

Таким образом, после того, как адрес станет временным в классе Employee при запуске программы, вы получите исключение nullPointerException, потому что во время десериализации ссылка на адрес будет равна нулю.

Случай 3. Что делать, если вы все же хотите сохранить состояние ссылочного объекта (например, указанного выше адресного объекта):

Если вы сделаете адрес временным, то во время десериализации он вернет null. Но что, если вы все еще хотите иметь такое же состояние, как и при сериализованном адресном объекте. Java-сериализация предоставляет такой механизм, что если у вас есть частные методы с определенной подписью, они получат вызывается во время сериализации и десериализации, поэтому, если мы предоставим методы writeObject и readObject класса сотрудника, они будут вызываться во время сериализации и десериализации объекта Employee.

Employee.java:

Следует иметь в виду, что ObjectInputStream должен читать данные в той же последовательности, в которой мы записали данные в ObjectOutputStream.
Создайте Address.java в org.arpit.javapostsforlearning
Address.java:

Создайте SerializeDeserializeMain.java в org.arpit.javapostsforlearning

SerializeDeserializeMain.java:

Запустить:

Когда вы запустите SerializeDeserializeMain.java. Вы получите следующий вывод

Deserialized Employee...
Emp id: 101
Name: Arpit
Department: CS
City :Pune

Итак, теперь мы получили то же состояние адресного объекта, что и до сериализации.

Наследование в сериализации в java:

Теперь мы посмотрим, как наследование влияет на сериализацию. Таким образом, может быть несколько случаев, независимо от того, является ли суперкласс сериализуемым или нет. Если нет, то как вы с этим справитесь и как это работает.

Давайте посмотрим на примере.
Мы создадим Person.java, который будет суперклассом Employee.

Случай 4: Что, если суперкласс является сериализуемым?
Если суперкласс сериализуем, то все его подклассы становятся сериализуемыми автоматически.

Случай 5. Что делать, если суперкласс не сериализуем?
Если суперкласс не сериализуем, то мы должны обрабатывать его совершенно по-другому.

  • Если суперкласс не сериализуемый, он не должен иметь конструктора аргументов.

Person.java

Создайте Employee.java в org.arpit.javapostsforlearning
Employee.java:

Создайте SerializeDeserializeMain.java в org.arpit.javapostsforlearning

SerializeDeserializeMain.java:

Запустить:

Когда вы запустите SerializeDeserializeMain.java. Вы получите следующий вывод

Если суперкласс не является сериализуемым, то все значения переменных экземпляра, унаследованных от суперкласса, будут инициализированы путем вызова конструктора несериализуемого суперкласса во время процесса десериализации. поэтому здесь имя наследуется от человека, поэтому во время десериализация, имя инициализируется по умолчанию.

Случай 6. Что делать, если суперкласс является сериализуемым, но вы не хотите, чтобы подкласс был сериализуемым
Если вы не хотите, чтобы подкласс был Serializable, вам необходимо реализовать методы writeObject() и readObject() в subclass и необходимо выбросить NotSerializableException из этих методов.

Случай 7. Можно ли сериализовать статические переменные?
Нет, нельзя. Как вы знаете, статическая переменная находится на уровне класса, а не на уровне объекта, и вы сериализуете объект, поэтому вы не можете сериализовать статические переменные.

Интерфейс Externalizable можно использовать вместо сериализуемого, если вам нужен больший контроль над сериализацией. Подробнее об этом можно прочитать в Externalizable in java.

Учебное пособие по сериализации Java:

Резюме:

  • Сериализация в java - это преобразование значений / состояний вашего Java-объекта в байты для отправки по сети или сохранения. С другой стороны, десериализация - это преобразование байтового кода в соответствующие java-объекты.
  • В сериализации хорошо то, что весь процесс не зависит от JVM, то есть объект может быть сериализован на одной платформе и десериализован на совершенно другой платформе.
  • Если вы хотите сериализовать какой-либо класс, он должен реализовать интерфейс Serializable, который является интерфейсом маркера.
  • Интерфейс маркера в Java - это интерфейс без поля или методов, или, говоря простым языком, пустой интерфейс в Java называется интерфейсом маркера.
  • SerialVersionUID используется для того, чтобы гарантировать, что тот же объект (который использовался во время сериализации) был загружен во время десериализации. SerialVersionUID используется для контроля версий объекта.
  • Когда вы сериализуете любой объект и если он содержит ссылку на какой-либо другой объект, то сериализация Java сериализует весь граф этого объекта.
  • Если вы не хотите сериализовать какое-либо поле, сделайте его временным.
  • Если суперкласс Serializable, то его подклассы автоматически становятся сериализуемыми.
  • Если суперкласс не является сериализуемым, тогда все значения переменных экземпляра, унаследованные от суперкласса, будут инициализированы путем вызова конструктора несериализуемого суперкласса в процессе десериализации.
  • Если вы не хотите, чтобы подкласс был сериализуемым, вам необходимо реализовать методы writeObject () и readObject () и выбросить NotSerializableException из этих методов.
  • Статические переменные нельзя сериализовать.

Вам также может понравиться:

Это все о сериализации в java.