logo

Серіалізація та десеріалізація в Java з прикладом

Серіалізація - це механізм перетворення стану об'єкта в потік байтів. Десеріалізація — це зворотний процес, коли потік байтів використовується для відтворення фактичного об’єкта Java у пам’яті. Цей механізм використовується для збереження об’єкта. serialize-deserialize-java
Створений потік байтів не залежить від платформи. Таким чином, об’єкт, серіалізований на одній платформі, може бути десеріалізований на іншій платформі. Щоб зробити серіалізованим об’єкт Java, ми реалізуємо java.io.Serializable інтерфейс. Клас ObjectOutputStream містить writeObject() метод серіалізації об'єкта.

public final void writeObject(Object obj)  throws IOException>

Клас ObjectInputStream містить readObject() метод десеріалізації об'єкта.

public final Object readObject()  throws IOException,  ClassNotFoundException>

Переваги серіалізації



  1. Щоб зберегти/зберегти стан об’єкта.
  2. Для переміщення об’єкта по мережі.

Серіалізувати можна лише об’єкти тих класів, які реалізуються java.io.Serializable інтерфейс. Серіалізований - це a інтерфейс маркера (не має члена даних і методу). Він використовується для позначення класів Java, щоб об’єкти цих класів могли отримати певні можливості. Інші приклади інтерфейсів маркерів: - Cloneable і Remote.

Пункти, які слід пам’ятати

1. Якщо батьківський клас реалізував інтерфейс Serializable, то дочірньому класу не потрібно його реалізовувати, але навпаки не вірно.
2. Лише нестатичні елементи даних зберігаються за допомогою процесу серіалізації.
3. Статичні елементи даних і тимчасові елементи даних не зберігаються через процес серіалізації. Отже, якщо ви не хочете зберігати значення нестатичного елемента даних, зробіть його тимчасовим.
4. Конструктор об'єкта ніколи не викликається, коли об'єкт десеріалізовано.
5. Асоційовані об’єкти повинні реалізовувати інтерфейс Serializable. приклад:

class A implements Serializable{  // B also implements Serializable // interface. B ob=new B();  }>

SerialVersionUID Середа виконання серіалізації пов’язує номер версії з кожним класом Serializable під назвою SerialVersionUID, який використовується під час десеріалізації для перевірки того, що відправник і одержувач серіалізованого об’єкта завантажили класи для цього об’єкта, які сумісні щодо серіалізації. Якщо одержувач завантажив клас для об’єкта, який має UID, відмінний від відповідного класу відправника, десеріалізація призведе до InvalidClassException .

Клас Serializable може явно оголосити свій власний UID, оголосивши назву поля. Він має бути статичним, кінцевим і мати довгий тип. тобто- ANY-ACCESS-MODIFIER static final long serialVersionUID=42L; Якщо серіалізований клас явно не оголошує serialVersionUID, тоді середовище виконання серіалізації обчислить значення за замовчуванням для цього класу на основі різних аспектів класу, як описано в Специфікації серіалізації об’єктів Java. Однак наполегливо рекомендується, щоб усі серіалізовані класи явно оголошували значення serialVersionUID, оскільки його обчислення дуже чутливе до деталей класу, які можуть відрізнятися залежно від реалізації компілятора, будь-які зміни в класі або використання іншого ідентифікатора можуть вплинути на серіалізовані дані. Також рекомендується використовувати приватний модифікатор для UID, оскільки він не корисний як успадкований член. serialver Serialver — це інструмент, який постачається разом із JDK. Він використовується для отримання номера serialVersionUID для класів Java.

Ви можете виконати таку команду, щоб отримати serialVersionUID serialver [-classpath шлях до класу] [-show] [classname…] Приклад 1:

Java




// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Demo>implements> java.io.Serializable> {> >public> int> a;> >public> String b;> >// Default constructor> >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>, 'geeksforgeeks');> >String filename = 'file.ser';> > >// Serialization> >try> >{> >//Saving of object in a file> >FileOutputStream file =>new> FileOutputStream(filename);> >ObjectOutputStream out =>new> ObjectOutputStream(file);> > >// Method for serialization of object> >out.writeObject(object);> > >out.close();> >file.close();> > >System.out.println('Object has been serialized');> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> >Demo object1 =>null>;> >// Deserialization> >try> >{> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream(filename);> >ObjectInputStream in =>new> ObjectInputStream(file);> > >// Method for deserialization of object> >object1 = (Demo)in.readObject();> > >in.close();> >file.close();> > >System.out.println('Object has been deserialized ');> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> > >catch>(ClassNotFoundException ex)> >{> >System.out.println('ClassNotFoundException is caught');> >}> >}> }>

>

>

Вихід:

Object has been serialized Object has been deserialized  a = 1 b = geeksforgeeks>

приклад 2:

обхід попереднього замовлення

Java




завантажити відео з youtube за допомогою vlc

// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Emp>implements> Serializable {> private> static> final> long> serialversionUID => >129348938L;> >transient> int> a;> >static> int> b;> >String name;> >int> age;> >// Default constructor> public> Emp(String name,>int> age,>int> a,>int> b)> >{> >this>.name = name;> >this>.age = age;> >this>.a = a;> >this>.b = b;> >}> }> public> class> SerialExample {> public> static> void> printdata(Emp object1)> >{> >System.out.println('name = ' + object1.name);> >System.out.println('age = ' + object1.age);> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> public> static> void> main(String[] args)> >{> >Emp object =>new> Emp('ab',>20>,>2>,>1000>);> >String filename = 'shubham.txt';> >// Serialization> >try> {> >// Saving of object in a file> >FileOutputStream file =>new> FileOutputStream> >(filename);> >ObjectOutputStream out =>new> ObjectOutputStream> >(file);> >// Method for serialization of object> >out.writeObject(object);> >out.close();> >file.close();> >System.out.println('Object has been serialized '> >+ 'Data before Deserialization.');> >printdata(object);> >// value of static variable changed> >object.b =>2000>;> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >object =>null>;> >// Deserialization> >try> {> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream> >(filename);> >ObjectInputStream in =>new> ObjectInputStream> >(file);> >// Method for deserialization of object> >object = (Emp)in.readObject();> >in.close();> >file.close();> >System.out.println('Object has been deserialized '> >+ 'Data after Deserialization.');> >printdata(object);> >// System.out.println('z = ' + object1.z);> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >catch> (ClassNotFoundException ex) {> >System.out.println('ClassNotFoundException' +> >' is caught');> >}> >}> }>

>

>

Вихід:

Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000>

Опис результату: Ви бачили, що під час десеріалізації об’єкта значення a і b змінилися. Причина: a була позначена як тимчасова, а b — статична.

В випадку перехідні змінні: - Змінна, визначена за допомогою ключового слова transient, не серіалізується під час процесу серіалізації. Цю змінну буде ініціалізовано значенням за замовчуванням під час десеріалізації. (наприклад: для об’єктів це null, для int – 0).

В випадку статичні змінні: - Змінна, визначена за допомогою ключового слова static, не серіалізується під час процесу серіалізації. Цю змінну буде завантажено з поточним значенням, визначеним у класі під час десеріалізації.

Перехідний проти остаточного:
остаточний змінні будуть брати участь у серіалізації безпосередньо своїми значеннями.
Отже, оголошення кінцевої змінної як тимчасової немає сенсу.
//компілятор присвоює значення кінцевій змінній

приклад:

final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->10, тому що x кінцеве. System.out.println(y);//20>> 

приклад 3:

Java




//java code for final with transient> import> java.io.*;> class> Dog>implements> Serializable{> >int> i=>10>;> >transient> final> int> j=>20>;> }> class> GFG {> >public> static> void> main (String[] args)>throws> IOException,ClassNotFoundException> >{> >Dog d1=>new> Dog();> >//Serialization started> >System.out.println(>'serialization started'>);> >FileOutputStream fos=>new> FileOutputStream(>'abc.ser'>);> >ObjectOutputStream oos=>new> ObjectOutputStream(fos);> >oos.writeObject(d1);> >System.out.println(>'Serialization ended'>);> > >//Deserialization started> >System.out.println(>'Deserialization started'>);> >FileInputStream fis=>new> FileInputStream(>'abc.ser'>);> >ObjectInputStream ois=>new> ObjectInputStream(fis);> >Dog d2=(Dog) ois.readObject();> >System.out.println(>'Deserialization ended'>);> >System.out.println(>'Dog object data'>);> >//final result> >System.out.println(d2.i+>' '> +d2.j);> >}> }>

>

Вихід

serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>