Что такое сериализация в Java?



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

Сериализация в - важная концепция, которая касается преобразования объектов в поток байтов для переноса объектов Java с одной виртуальной машины Java на другую и воссоздания их в исходной форме. Я выстрою список для этой статьи, как показано ниже:

Что такое сериализация в Java?

Сериализация в Java - это процесс преобразования кода Java Объект в Байтовый поток , чтобы перенести объектный код с одной виртуальной машины Java на другую и воссоздать его с помощью процесса Десериализация.





Serialization-in-Java-Edureka-Picture-1

Зачем нужна сериализация в Java ?

Нам нужна сериализация по следующим причинам:



  • Общение : Сериализация включает в себя процедуру объекта сериализация и коробка передач. Это позволяет нескольким компьютерным системам одновременно проектировать, совместно использовать и выполнять объекты.

  • Кеширование : Время, затрачиваемое на создание объекта, больше по сравнению со временем, необходимым для его десериализации. Сериализация сводит к минимуму затраты времени на кеширование гигантские объекты.

  • Глубокая копия : Клонирование Процесс упрощается с помощью сериализации. Точный копия объекта получаетсясериализация объекта в байтовый массив , а затем де-сериализовать его.



  • Пересекать Синхронизация JVM: Главное преимущество сериализации в том, что онаработает на разных JVM, которые могут работать на разных архитектуры или Операционные системы

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

Как мы сериализуем объект?

К Объект Java является сериализуемый тогда и только тогда, когда его класс или любой из его родительских классов реализуют либо Ява . я . Сериализуемый интерфейс или его подинтерфейс, java.io.Externalizable.

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

//Интерфейс

package Serial1 import java.io.Serializable открытый класс Employee реализует Serializable {private static final long serialVersionUID = 1L // UID серийной версии int id String name public Employee (int id, String name) {this.id = id this.name = name }}

// Сериализуем

package Serial1 import java.io. * class Persist {public static void main (String args []) {try {Employee emp1 = new Employee (20110, 'John') Employee emp2 = new Employee (22110, 'Jerry') Employee emp3 = новый сотрудник (20120, 'Sam') FileOutputStream fout = новый FileOutputStream ('output.txt') ObjectOutputStream out = новый ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Сериализация и десериализация успешно выполнены')} catch (Exception e) {System.out.println (e)}}}

Вывод:

Сериализация и десериализация успешно выполнены

Десериализация : Это процесс, обратный сериализации, когда сериализованный байтовый поток объекта от отправителя воссоздается на принимающей стороне.

как создать jframe

// Десериализация

package Serial1 import java.io. * class Depersist {public static void main (String args []) {попробуйте {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Сотрудник e1 = (Сотрудник) in.readObject ( ) Сотрудник e2 = (Сотрудник) in.readObject () Сотрудник e3 = (Сотрудник) in.readObject () System.out.println (e1.id + '' + e1.name) System.out.println (e2.id + '' + e2.name) System.out.println (e3.id + '' + e3.name) in.close ()} catch (Исключение e) {System.out.println (e)}}}

Вывод:

20110 Джон
22110 Джерри

20120 Сэм

Преимущества и недостатки сериализации в Java

Преимущества:

  • Процесс сериализации - это встроенный функция, которая не требует стороннего программного обеспечения для выполнения сериализации
  • Доказано, что процедура сериализации просто и легко понимать

  • Процедура сериализации универсальный и разработчики с разным опытом знакомы с ним

  • Легко использовать и просто настроить

  • Сериализованные потоки данных поддержка шифрования, сжатия, аутентификации и безопасные вычисления Java

  • Есть много критические технологии полагаясь на сериализацию.

Недостатки:

  • Объекты, пока DeSerialization становится хрупкий и они не уверены в том, что они будут эффективно десериализованы.

  • Переходные переменные объявляются, когда сериализация создает пространство памяти, но конструктор не вызывается, что приводит к сбою инициализации переходных переменных, что приводит к вариант Standard Java Flow.

  • Процесс сериализации неэффективный с точки зрения использования памяти.

  • Сериализацию нежелательно использовать в приложениях, которым требуется одновременный доступ без требования сторонние API , поскольку сериализация не предлагает никакого механизма управления переходом для каждого SE.

  • Процедура сериализации не предлагает мелкозернистый контроль для доступа к объектам.

Практические примеры сериализации в Java

Сериализация с использованием наследования

Случай - 1: Если суперкласс является сериализуемым, то по умолчанию его подклассы также сериализуемы.

В этом случае подкласс сериализуема по умолчанию, если суперкласс реализует Сериализуемый интерфейс

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class A реализует Serializable {int i public A (int i) {this.i = i}} класс B расширяет A {int j public B (int i, int j) {super (i) this.j = j}} public class Test {public static void main (String [] args) выдает исключение {B b1 = новый B (200 400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = new FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Объект был сериализован') FileInputStream fis = new FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Объект десериализован') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Вывод:

j = 20
Объект сериализован
Объект десериализован
я = 200
j = 400

в чем разница между java и c ++

Случай - 2: подкласс может быть сериализован, если он реализует сериализуемый интерфейс, даже если суперкласс не реализует сериализуемый интерфейс.

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

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class superclass {int i public superclass (int i) {this.i = i} public superclass () {i = 50 System.out.println ('Вызывается конструктор суперкласса')}} подкласс класса расширяет суперкласс реализует Serializable {int j общедоступный подкласс (int i, int j) {super (i) this.j = j }} открытый класс test2 {public static void main (String [] args) выдает исключение {подкласс b1 = новый подкласс (10, 20) System.out.println ('i =' + b1.i) System.out.println ( 'j =' + b1.j) FileOutputStream fos = new FileOutputStream ('output.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Объект был сериализован') FileInputStream fis = new FileInputStream ('output.ser') ObjectInputStream ois = new ObjectInputStream (fis) подкласс b2 = (подкласс) ois.readObject ( ) ois.close () fis.close () System.out.println ('Объект был десериализован') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Объект сериализован
Конструктор суперкласса называется
Объект десериализован
я = 50
j = 20

Случай - 3: Если суперкласс сериализуем, но нам не нужно сериализовать подкласс.

В этом случае сериализацию подкласса можно предотвратить.путем реализации writeObject () и readObject () методы в подклассе, и ему нужно выбросить NotSerializableException из этих методов.

пакет SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import java.io.NotSerializableException import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class Parentalizable class Parentalizable class Parent implementation {Serializial class Parent__ i public Parent (int i) {this.i = i}} дочерний класс расширяет Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) выбрасывает IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) бросает IOException {throw new NotSerializableException ()}} открытый класс test3 {public static void main (String [] args) выдает исключение {child b1 = new child (100, 200) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = new FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream ( fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Объект был сериализован ') FileInputStream fis = new FileInputStream (' abc.ser ') ObjectInputStream ois = new ObjectInputStream (fis) child b2 = (child) ois.readObject () ois.close () fis.close () System.out. println ('Объект десериализован') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Вывод:

я = 100
j = 200
Исключение в потоке main java.io.NotSerializableException
в SerializationInheritance.child.writeObject (test3.java:48)
в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод)

Сериализация с использованием статического члена

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

пакет stati import java.io. * class StaticSerial реализует Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('Во время сериализации статический член имеет значение: '+ i) try {FileOutputStream fos = new FileOutputStream (' F: File.ser ') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (ob) oos.close () i = 99 FileInputStream fis = new FileInputStream ('F: File.ser') ObjectInputStream ois = new ObjectInputStream (fis) ob = (StaticSerial) ois.readObject () ois.close () System.out.println ('После десериализации статический член имеет значение:' + i)} catch (Исключение e) {System.out.println (e)}}}

Вывод:

Во время сериализации статический член имеет значение: 100
После десериализации статический член имеет значение: 99

Внешний интерфейс

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

Интерфейс Externalizable доступен в java.io и предоставляет два метода:

  • public void writeExternal (ObjectOutput out) выбрасывает IOException
  • public void readExternal (ObjectInput in) выбрасывает IOException

Ключевые различия между сериализацией и возможностью внешнего использования заключаются в следующем:

  • Реализация : Внешний интерфейс исключает пользователя явно упомяните объекты для сериализации. В интерфейсе сериализации все объекты и переменные сериализуются в время выполнения.

  • Методы : Внешний интерфейс состоит из двух методов, а именно:

    • writeExternal ()

    • readExternal ()

Принимая во внимание, что Serializable Interface не включает никаких методов.

  • Обработать: Процесс сериализации во внешнем интерфейсе обеспечивает настройка к процессу сериализации. Но интерфейс сериализации предоставит по умолчанию процесс сериализации.

    установка пути к классу в java

  • Обратная совместимость и контроль: Внешний интерфейс поддерживает сериализацию независимо от управление версиями и единственная проблема заключается в том, что пользователь должен нести ответственность за сериализацию суперкласса. С другой стороны, для интерфейса сериализации требуется та же версия JVM на обоих концах, но включает автоматическую сериализацию всех объектов и классов, включая суперкласс.

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

package ext import java.io. * class Demo реализует java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} class Test {public static void main (String [] args) {Demo object = new Demo (1, 'Welcome to Edureka') String filename = 'file.ser' try {FileOutputStream file = new FileOutputStream (filename) ObjectOutputStream out = new ObjectOutputStream (file) out .writeObject (объект) out.close () file.close () System.out.println ('Объект был сериализован')} catch (IOException ex) {System.out.println ('IOException пойман')} Demo object1 = null try {FileInputStream file = new FileInputStream (filename) ObjectInputStream in = new ObjectInputStream (файл) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Объект был deserialized ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException перехвачено ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException перехвачен')}}}

Временное ключевое слово

Временное ключевое слово - это зарезервированное ключевое слово в Java. Он используется как изменение переменной во время процесса сериализации. Объявление переменной с ключевым словом Transient позволяет избежать сериализации переменной.

UID серийной версии

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

Споры о сериализации в Java

Oracle Архитекторы намерены удалить сериализацию из Java, поскольку считают ее Ужасная ошибка 1997 года . После напряженных исследований разработчики Oracle обнаружили несколько недостатков в конструкции процедуры сериализации, которые представляют угрозу для данных.

В 1997 годуМарк Рейнхольд заявляет: « Нам нравится называть сериализацию «подарком, который продолжает дарить», а тип подарка, который он продолжает дарить, - это уязвимости безопасности. Вероятно, треть всех уязвимостей Java связана с сериализацией, а может быть и больше половины. Это удивительно богатый источник уязвимостей, не говоря уже о нестабильности ».

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

Лучшие практики при использовании сериализации в Java

Ниже приведены несколько передовых практик, которым необходимо следовать.

  • Рекомендуется использовать javadoc @ серийный тег для обозначения сериализуемых полей.
  • В .быть Расширение предпочтительно использовать для файлов, представляющих сериализованные объекты.
  • Не рекомендуется подвергать какие-либо статические или переходные поля сериализация по умолчанию.
  • Расширяемые классы не следует сериализовать, если это не обязательное.
  • Внутренние классы следует избегать участия в сериализации.

На этом мы подошли к концу статьи. Надеюсь, вы поняли основы сериализации в Java, ее типы и функции.

Проверьте от Edureka, надежной компании по онлайн-обучению с сетью из более чем 250 000 довольных учащихся по всему миру. Курс обучения и сертификации по Java J2EE и SOA от Edureka предназначен для студентов и профессионалов, которые хотят стать Java-разработчиками. Курс разработан, чтобы дать вам хорошее начало в программировании на Java и обучить вас как основным, так и продвинутым концепциям Java, а также различным фреймворкам Java, таким как Hibernate и весна .

Есть вопрос к нам? Упомяните об этом в разделе комментариев к статье «Сериализация в Java», и мы свяжемся с вами как можно скорее.