logo

Serialisering og deserialisering i Java med eksempel

Serialisering er en mekanisme til at konvertere et objekts tilstand til en bytestrøm. Deserialisering er den omvendte proces, hvor bytestrømmen bruges til at genskabe det faktiske Java-objekt i hukommelsen. Denne mekanisme bruges til at fastholde objektet. serialize-deserialize-java
Den oprettede bytestrøm er platformsuafhængig. Så objektet serialiseret på én platform kan deserialiseres på en anden platform. For at gøre et Java-objekt serialiserbart implementerer vi java.io.Serialiserbar interface. ObjectOutputStream-klassen indeholder skriveObject() metode til at serialisere et objekt.

public final void writeObject(Object obj)  throws IOException>

ObjectInputStream-klassen indeholder readObject() metode til at deserialisere et objekt.



public final Object readObject()  throws IOException,  ClassNotFoundException>

Fordele ved serialisering

  1. At gemme/bevare et objekts tilstand.
  2. At rejse et objekt på tværs af et netværk.

Kun objekterne i de klasser kan serialiseres, som implementeres java.io.Serialiserbar interface. Serialiserbar er en markørgrænseflade (har intet datamedlem og metode). Det bruges til at markere java-klasser, så objekter i disse klasser kan få en vis kapacitet. Andre eksempler på markørgrænseflader er: - Klonbar og Remote.



Punkter at huske

1. Hvis en overordnet klasse har implementeret Serializable-grænseflade, behøver børneklassen ikke at implementere det, men omvendt er det ikke sandt.
2. Kun ikke-statiske datamedlemmer gemmes via serialiseringsprocessen.
3. Statiske datamedlemmer og forbigående datamedlemmer gemmes ikke via serialiseringsprocessen. Så hvis du ikke vil gemme værdien af ​​et ikke-statisk datamedlem, så gør det forbigående.
4. Konstruktor af objekt kaldes aldrig, når et objekt er deserialiseret.
5. Tilknyttede objekter skal implementere Serializable grænseflade. Eksempel:

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

SerialVersionUID Serialiseringens runtime knytter et versionsnummer til hver Serializable-klasse kaldet en SerialVersionUID, som bruges under Deserialization til at verificere, at afsender og modtager af et serialiseret objekt har indlæste klasser for det objekt, som er kompatible med hensyn til serialisering. Hvis modtageren har indlæst en klasse for objektet, der har en anden UID end den tilsvarende afsenderens klasse, vil deserialiseringen resultere i en InvalidClassException .



En serialiserbar klasse kan erklære sit eget UID eksplicit ved at erklære et feltnavn. Den skal være statisk, endelig og af typen lang. dvs. ANY-ACCESS-MODIFIER static final long serialVersionUID=42L; Hvis en serialiserbar klasse ikke eksplicit erklærer et serialVersionUID, vil serialiserings-runtime beregne en standard for den klasse baseret på forskellige aspekter af klassen, som beskrevet i Java Object Serialization Specification. Det anbefales dog kraftigt, at alle klasser, der kan serialiseres, eksplicit erklærer serialVersionUID-værdi, da dens beregning er meget følsom over for klassedetaljer, der kan variere afhængigt af compilerimplementeringer, enhver ændring i klasse eller brug af andet id kan påvirke de serialiserede data. Det anbefales også at bruge privat modifikator til UID, da det ikke er nyttigt som nedarvet medlem. seriever Serialveren er et værktøj, der følger med JDK. Det bruges til at få serialVersionUID-nummer for Java-klasser.

Du kan køre følgende kommando for at få serialVersionUID serialver [-classpath classpath] [-show] [classname...] Eksempel 1:

Java


java hashmap



// 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');> >}> >}> }>

>

>

Output:

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

Eksempel 2:

Java




rohit shetty skuespiller

// 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');> >}> >}> }>

>

>

Produktion:

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>

Beskrivelse for output: Du har set, mens du deserialiserer objektet, at værdierne af a og b er ændret. Årsagen til at a var markeret som forbigående og b var statisk.

I tilfælde af forbigående variabler:- En variabel defineret med forbigående nøgleord serialiseres ikke under serialiseringsprocessen. Denne variabel vil blive initialiseret med standardværdien under deserialisering. (f.eks.: for objekter er den nul, for int er den 0).

I tilfælde af statiske variabler:- En variabel defineret med statisk nøgleord serialiseres ikke under serialiseringsprocessen. Denne variabel vil blive indlæst med den aktuelle værdi defineret i klassen under deserialisering.

Transient vs Final:
endelig variabler vil blive deltaget i serialisering direkte af deres værdier.
Derfor er det ingen nytte at erklære en endelig variabel som forbigående.
//kompileren tildeler værdien til den endelige variabel

eksempel:

final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->10 fordi x er endelig. System.out.println(y);//20>

Eksempel 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);> >}> }>

>

>

Produktion

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