Serializarea este un mecanism de conversie a stării unui obiect într-un flux de octeți. Deserializarea este procesul invers în care fluxul de octeți este utilizat pentru a recrea obiectul Java real în memorie. Acest mecanism este folosit pentru a persista obiectul.
Fluxul de octeți creat este independent de platformă. Deci, obiectul serializat pe o platformă poate fi deserializat pe o altă platformă. Pentru a face un obiect Java serializat, implementăm java.io.Serializabil interfata. Clasa ObjectOutputStream conține scrieObject() metoda de serializare a unui obiect.
public final void writeObject(Object obj) throws IOException>
Clasa ObjectInputStream conține readObject() metoda de deserializare a unui obiect.
public final Object readObject() throws IOException, ClassNotFoundException>
Avantajele serializării
- Pentru a salva/persiste starea unui obiect.
- Pentru a călători un obiect printr-o rețea.
Numai obiectele acelor clase care sunt implementate pot fi serializate java.io.Serializabil interfata. Serializabil este a interfata markerului (nu are membru de date și metodă). Este folosit pentru a marca clasele java, astfel încât obiectele acestor clase pot obține anumite capacități. Alte exemple de interfețe de marcare sunt: - Clonabil și la distanță.
Puncte de reținut
1. Dacă o clasă părinte a implementat o interfață Serializable, atunci clasa copil nu trebuie să o implementeze, dar invers nu este adevărat.
2. Numai membrii de date non-statici sunt salvați prin procesul de serializare.
3. Membrii de date statice și membrii de date tranzitori nu sunt salvați prin procesul de serializare. Deci, dacă nu doriți să salvați valoarea unui membru de date non-static, atunci faceți-l tranzitoriu.
4. Constructorul de obiect nu este niciodată apelat atunci când un obiect este deserializat.
5. Obiectele asociate trebuie să implementeze interfața Serializable. Exemplu:
class A implements Serializable{ // B also implements Serializable // interface. B ob=new B(); }>
SerialVersionUID Runtime Serialization asociază un număr de versiune cu fiecare clasă Serializable numit SerialVersionUID, care este utilizat în timpul deserializării pentru a verifica dacă expeditorul și receptorul unui obiect serializat au încărcate clase pentru acel obiect care sunt compatibile cu serializarea. Dacă receptorul a încărcat o clasă pentru obiectul care are un UID diferit de cel al clasei expeditorului corespunzătoare, deserializarea va avea ca rezultat un InvalidClassException .
O clasă Serializabil își poate declara propriul UID în mod explicit prin declararea unui nume de câmp. Trebuie să fie static, final și de tip lung. i.e- ANY-ACCES-MODIFIER static final long serialVersionUID=42L; Dacă o clasă serializabilă nu declară în mod explicit un serialVersionUID, atunci timpul de rulare a serializării va calcula unul implicit pentru acea clasă pe baza diferitelor aspecte ale clasei, așa cum este descris în Specificația de serializare a obiectelor Java. Cu toate acestea, este recomandat ca toate clasele serializabile să declare în mod explicit valoarea serialVersionUID, deoarece calculul său este foarte sensibil la detaliile clasei care pot varia în funcție de implementările compilatorului, orice modificare a clasei sau utilizarea unui id diferit poate afecta datele serializate. De asemenea, se recomandă utilizarea modificatorului privat pentru UID, deoarece nu este util ca membru moștenit. serialver Serialver-ul este un instrument care vine cu JDK. Este folosit pentru a obține numărul serialVersionUID pentru clasele Java.
Puteți rula următoarea comandă pentru a obține serialVersionUID serialver [-classpath classpath] [-show] [classname...] Exemplul 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');> > }> > }> }> |
>
>
Ieșire:
Object has been serialized Object has been deserialized a = 1 b = geeksforgeeks>
Exemplul 2:
Java
// 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');> > }> > }> }> |
>
>
Ieșire:
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>
Descriere pentru ieșire: ați văzut în timpul deserializării obiectului că valorile lui a și b s-au schimbat. Motivul fiind a a fost marcat ca tranzitoriu și b a fost static.
In caz de variabile tranzitorii:- O variabilă definită cu cuvântul cheie tranzitoriu nu este serializată în timpul procesului de serializare. Această variabilă va fi inițializată cu valoarea implicită în timpul deserializării. (de exemplu: pentru obiecte este nul, pentru int este 0).
In caz de Variabile statice:- O variabilă definită cu cuvântul cheie static nu este serializată în timpul procesului de serializare. Această variabilă va fi încărcată cu valoarea curentă definită în clasă în timpul deserializării.
greierul meu
Tranzitoriu vs final:
final variabilele vor fi implicate la serializare direct prin valorile lor.
Prin urmare, declararea unei variabile finale ca fiind tranzitorie nu are rost.
//compilatorul atribuie valoarea variabilei finale
exemplu:
final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->10 deoarece x este final. System.out.println(y);//20>
Exemplul 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);> > }> }> |
>
>Ieșire
serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>