Care este conceptul serializării în Java?



Acest articol vă va ajuta cu o abordare cuprinzătoare față de conceptul de serializare în Java, împreună cu exemple în timp real pentru o mai bună înțelegere.

Serializare în este un concept important care se ocupă cu conversia obiectelor într-un flux de octeți pentru a transporta obiectele java de la o mașină virtuală Java la cealaltă și a le recrea în forma originală. Voi alinia dosarul pentru acest articol după cum urmează:

Ce este serializarea în Java?

Serializare în Java este procesul de conversie a codului Java Obiect intr-o Flux de octeți , pentru a transfera codul obiectului de la o mașină virtuală Java la alta și a-l recrea folosind procesul de Deserializarea.





Serialization-in-Java-Edureka-Picture-1

De ce avem nevoie de serializare în Java ?

Avem nevoie de serializare din următoarele motive:



  • Comunicare : Serializarea implică procedura obiectului serializare și transmitere. Aceasta permite mai multor sisteme informatice să proiecteze, să partajeze și să execute obiecte simultan.

  • Caching : Timpul consumat la construirea unui obiect este mai mult comparativ cu timpul necesar pentru demerializarea acestuia. Serializarea minimizează consumul de timp cu stocarea în cache obiectele uriașe.

  • Deep Copy : Clonarea procesul este simplificat prin utilizarea serializării. Exact replica a unui obiect se obține prinserializarea obiectului către un matrice de octeți , și apoi de-serializarea acestuia.



  • Cruce Sincronizare JVM: Avantajul major al serializării este că acestafuncționează pe diferite JVM-uri care ar putea rula pe diferite arhitecturi sau Sisteme de operare

  • Persistenţă: Starea oricărui obiect poate fi stocată direct prin aplicarea serializării pe acesta și stocată într-un Bază de date ca să poată fi recuperat mai târziu.

Cum serializăm un obiect?

LA Obiect Java este serializabil dacă și numai dacă clasa sa sau oricare dintre clasele sale părinte implementează fie java . Eu . Serializabil interfață sau subinterfața sa, java.io.Externalizabil.

În procesul de serializare, convertim starea unui obiect într-un flux de octeți, astfel încât să poată fi transferat de la o JVM la alta și să readucem fluxul de octeți înapoi în obiectul original.

// Interfață

pachet Serial1 import java.io.Serializable public class Employee implements Serializable {private static final long serialVersionUID = 1L // Serial Version UID int id Numele șirului Angajat public (int id, String name) {this.id = id this.name = name }}

// Serializați

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 = new Employee (20120, 'Sam') FileOutputStream fout = new FileOutputStream ('output.txt') ObjectOutputStream out = new ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Serializarea și deserializarea a fost executată cu succes')} catch (Excepție e) {System.out.println (e)}}}

Ieșire:

Serializarea și Deserializarea au fost executate cu succes

Deserializarea : Este procesul invers al serializării în care fluxul de octeți serializați al unui obiect de la expeditor este recreat la capătul receptor.

// Deserializați

package Serial1 import java.io. * class Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Employee e1 = (Employee) in.readObject ( ) Angajat e2 = (Angajat) in.readObject () Angajat e3 = (Angajat) 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 (Excepție e) {System.out.println (e)}}}

Ieșire:

20110 Ioan
22110 Jerry

20120 Sam

Avantajele și dezavantajele serializării în Java

Avantaje:

  • Procesul de serializare este un incorporat caracteristică care nu necesită software terță parte pentru a executa serializarea
  • Procedura de serializare este dovedită a fi simplu și uşor a întelege

  • Procedura de serializare este universal iar dezvoltatorii din medii diferite îi sunt familiarizați

  • Este ușor de utilizat și simplu de personalizat

  • Fluxuri de date serializate suport criptare, compresie, autentificare și calcul securizat Java

  • Sunt multi tehnologii critice bazându-se pe serializare.

Dezavantaje:

  • Obiecte în timp ce DeSerializarea devine fragil și nu sunt siguri că vor fi serializate eficient.

  • Variabilele tranzitorii declarate în timp ce Serializarea creează spațiu de memorie, dar nu se numește constructorul, ceea ce duce la eșecul inițializării variabilelor tranzitorii, rezultând variație la Fluxul Java Standard.

  • Procesul de serializare este ineficace în ceea ce privește utilizarea memoriei.

  • Serializarea nu este de preferat să fie utilizată în aplicațiile care au nevoie acces concurent fără cerința de API-uri terță parte , deoarece serializarea nu oferă niciun mecanism de control al tranziției pentru fiecare SE.

  • Procedura de serializare nu este oferită control cu ​​granulație fină pentru a accesa obiecte.

Exemple practice de serializare în Java

Serializarea folosind moștenirea

Caz - 1: Dacă Superclasa este serializabilă, atunci, în mod implicit, subclasele sale sunt, de asemenea, serializabile.

În acest caz, subclasă este serializabil în mod implicit dacă superclasă implementează Interfață serializabilă

package SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class A implements Serializable {int i public A (int i) {this.i = i}} clasa B extinde A {int j public B (int i, int j) {super (i) this.j = j}} public class Test {public static void main (String [] args) throws Exception {B b1 = new 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 ('Obiectul a fost serializat') FileInputStream fis = new FileInputStream ('abc.ser') ObjectInputStream ois = nou ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Obiectul a fost deserializat') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Ieșire:

j = 20
Obiectul a fost serializat
Obiectul a fost deserializat
i = 200
j = 400

Cazul 2: O subclasă poate fi serializată dacă implementează interfața serializabilă chiar dacă o superclasă nu implementează interfața serializabilă.

În acest caz, dacă superclasă nu implementează Interfață serializabilă , apoi, obiectele din subclasă poate fi serializat manual prin implementarea interfeței serializabile în subclasă.

package 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 ('Superclass constructor called')}} clasa subclasă extinde superclass implements Serializable {int j public subclasă (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) throws Exception {subclasă b1 = subclasă nouă (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 ('Obiectul a fost serializat') FileInputStream fis = new FileInputStream ('output.ser') ObjectInputStream ois = new ObjectInputStream (fis) subclasă b2 = (subclasă) ois.readObject ( ) ois.close () fis.close () System.out.println ('Obiectul a fost deserializat') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Obiectul a fost serializat
Constructor de superclasă numit
Obiectul a fost deserializat
i = 50
j = 20

ce este bucătar și marionetă

Cazul 3: Dacă superclasa este serializabilă, dar nu avem nevoie de subclasă pentru a fi serializată.

În acest caz, Serializarea subclasei poate fi prevenităprin implementarea writeObject () și readObject () metodele din subclasă și trebuie să arunce NotSerializableException din aceste metode.

pachet 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 I public Parent (int i) {this.i = i}} child class extends Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) aruncă IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) throws IOException {throw new NotSerializableException ()}} public class test3 {public static void main (String [] args) throws Exception {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 ('Object a fost serializat ') FileInputStream fis = new FileInputStream (' abc.ser ') ObjectInputStream ois = new ObjectInputStream (fis) child b2 = (child) ois.readObject () ois.close () fis.close () System.out. println ('Obiectul a fost deserializat') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Ieșire:

i = 100
j = 200
Excepție în firul „principal” java.io.NotSerializableException
la SerializationInheritance.child.writeObject (test3.java:48)
la sun.reflect.NativeMethodAccessorImpl.invoke0 (Metoda nativă)

Serializarea folosind un membru static

Serializarea câmpului membru static este ignorată în procesul de serializare. Serializarea estelegată de cea mai recentă stare a obiectului. Prin urmare, doar datele asociate cu o instanță specifică a unei clase suntserializat, dar nu câmpul membru static.

package stati import java.io. * class StaticSerial implements Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('La momentul Serializării, membru static are valoare: '+ 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 ('După Deserializare, membrul static are valoare:' + i)} catch (Excepție e) {System.out.println (e)}}}

Ieșire:

În momentul serializării, membrul static are valoarea: 100
După Deserializare, membrul static are valoarea: 99

Interfață externalizabilă

Interfață externalizabilă în Java este similar cu serializarea, dar singura diferență este că este capabil să ofere serializare personalizată unde veți decide obiectele care vor fi rănite în flux.

Interfața externalizabilă este disponibilă în java.io și oferă două metode:

  • public void writeExternal (ObjectOutput out) aruncă IOException
  • public void readExternal (ObjectInput in) aruncă IOException

Diferențele cheie dintre serializare și externalizare sunt următoarele:

  • Implementare : Interfață externalizabilă, cu excepția utilizatorului explicit menționați obiectele care urmează a fi serializate. În timp ce se află în interfața de serializare, toate obiectele și variabilele sunt serializate în timp de rulare.

  • Metode : Interfața externalizabilă constă din două metode, și anume:

    • writeExternal ()

    • readExternal ()

În timp ce, interfața serializabilă nu include nicio metodă.

  • Proces: Procesul de serializare în interfața externalizabilă oferă personalizare la procesul de serializare. Dar, Serialization Interface va furniza Mod implicit procesul de serializare.

  • Compatibilitate și control înapoi: Interfața externalizabilă acceptă serializarea indiferent de controlul versiunii iar singura problemă este că utilizatorul trebuie să fie responsabil în timp ce serializează Super Class. Pe de altă parte, interfața de serializare necesită aceeași versiune de JVM-uri la ambele capete, dar încorporează serializarea automată a tuturor obiectelor și claselor, inclusiv a superclasei.

  • Constructor public fără argumente: Nevoile de interfață de externalizare Constructor public fără argumente pentru a reconstitui obiectul serializat. În timp ce interfața de serializare nu necesită No-Arg Constructor, în schimb, folosește reflecţie pentru a reconstitui obiectul sau clasa serializată.

pachet ext import java.io. * clasa Demo implementează 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 (object) out.close () file.close () System.out.println ('Obiectul a fost serializat')} catch (IOException ex) {System.out.println ('IOException is caught')} Demo object1 = null try {FileInputStream file = new FileInputStream (file name) ObjectInputStream in = new ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Object a fost deserializat ') 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')}}}

Cuvânt cheie tranzitorie

Cuvântul cheie tranzitoriu este un cuvânt cheie rezervat în Java. Este folosit ca modificare variabilă în momentul procesului de serializare. Declararea unei variabile cu cuvânt cheie tranzitorie evită ca variabila să fie Serializată.

UID versiune serial

Înainte de a începe procesul de serializare, fiecare clasă / obiect serializabil se asociază cu un număr unic de identificare furnizat de JVM al mașinii gazdă. Acest ID unic se numește UID versiune serial . Acest UID este utilizat ca o identificare de către JVM a capătului de recepție pentru a confirma că același obiect este DeSerializat la capătul de recepție.

Controversele serializării în Java

Oracle’s Arhitecții intenționează să elimine Serializarea din Java, deoarece consideră că este un Greșeală oribilă din 1997 . După cercetări agitate, dezvoltatorii de la Oracle au descoperit câteva defecte în proiectarea procedurii de serializare care reprezintă o amenințare pentru date.

În anul 1997,Mark Reinhold afirmă - „ Ne place să numim serializarea „cadoul care continuă să fie oferit”, iar tipul de cadou pe care îl continuă să ofere este vulnerabilitățile de securitate. Probabil o treime din toate vulnerabilitățile Java au implicat serializarea, aceasta putând fi peste jumătate. Este o sursă uimitor de fecundă de vulnerabilități, ca să nu mai vorbim de instabilități. ”.

Există șanse ca serializarea să fie eliminată sau înlocuită în actualizările viitoare ale Java și, pe de altă parte, pentru un începător în Java, Serializarea nu ar putea fii o opțiune idealistă în proiectele lor

Cele mai bune practici în timpul utilizării serializării în Java

Următoarele sunt câteva bune practici care trebuie respectate

  • Se recomandă utilizarea javadoc @ etichetă serial pentru denotarea câmpurilor serializabile.
  • .a fi extensia este preferată a fi utilizată pentru fișierele care reprezintă obiecte serializate.
  • Nu este recomandat să fie supus niciunui câmp static sau tranzitoriu serializare implicită.
  • Clase extensibile nu trebuie serializat decât dacă este obligatoriu.
  • Clase interioare trebuie evitat să fie implicat în serializare.

Cu aceasta, am ajuns la sfârșitul acestui articol. Sper că ați înțeles elementele de bază ale serializării în Java, tipurile și funcționalitățile sale.

Verificați de Edureka, o companie de învățare online de încredere, cu o rețea de peste 250.000 de elevi mulțumiți răspândiți pe tot globul. Cursul de formare și certificare Java J2EE și SOA al Edureka este conceput pentru studenți și profesioniști care doresc să fie dezvoltator Java. Cursul este conceput pentru a vă oferi un început avansat în programarea Java și pentru a vă instrui atât pentru conceptele Java de bază, cât și pentru cele avansate, împreună cu diverse cadre Java, cum ar fi Hibernate și Primăvară .

Ai o întrebare pentru noi? Menționați-l în secțiunea de comentarii a acestui articol „Serializare în Java” și vă vom contacta cât mai curând posibil.