Quin és el concepte de serialització a Java?

Aquest article us ajudarà amb un enfocament complet cap al concepte de serialització a Java juntament amb exemples en temps real per a una millor comprensió.

Serialització a és un concepte important que tracta de la conversió d’objectes en un flux de bytes per transportar els objectes java d’una màquina virtual Java a l’altra i recrear-los a la forma original. Alinearé l’expedient d’aquest article de la manera següent:



Què és la serialització a Java?

Serialització a Java és el procés de conversió del codi Java Objecte en un Byte Stream , per transferir el codi objecte d'una màquina virtual Java a una altra i recrear-lo mitjançant el procés de Deserialització.

Serialization-in-Java-Edureka-Picture-1

Per què necessitem la serialització? a Java ?

Necessitem la serialització pels motius següents:



  • Comunicació : La serialització implica el procediment de l'objecte serialització i transmissió. Això permet a diversos sistemes informàtics dissenyar, compartir i executar objectes simultàniament.

  • Memòria cau : El temps consumit en construir un objecte es compara més amb el temps necessari per des serialitzar-lo. La serialització minimitza el consum de temps emmagatzematge en memòria cau els objectes gegants.

  • Còpia profunda : Clonació el procés es fa senzill mitjançant la serialització. Un exacte rèplica d'un objecte s'obté mitjançantserialitzant l'objecte a matriu de bytes i, a continuació, des serialitzant-lo.



  • Creu Sincronització de JVM: L’avantatge principal de la serialització és quefunciona en diferents JVM que podrien funcionar en diferents arquitectures o bé Sistemes operatius

  • Persistència: L'estat de qualsevol objecte es pot emmagatzemar directament aplicant-hi serialització i emmagatzemar-lo en un fitxer base de dades perquè pugui ser recuperat més tard.

Com serialitzem un objecte?

A Objecte Java és serialitzable si i només si la seva classe o qualsevol de les seves classes pares implementen el fitxer java . Jo . Serialitzable interfície o la seva subinterfície, java.io.Externalizable.

Al procés de serialització, convertim l’estat d’un objecte en un flux de bytes perquè es pugui transferir d’una JVM a l’altra i revertim el flux de bytes de nou a l’objecte original.

// Interfície

paquet Importació sèrie1 java.io.Serializable public class Employee implements Serializable {private static final long serialVersionUID = 1L // Versió de sèrie UID int id Nom de la cadena Employee public (int id, Nom de la cadena) {this.id = id this.name = name }}

// Serialitza

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 ('La serialització i la deserialització s'han executat correctament')} catch (Excepció e) {System.out.println (e)}}}

Sortida:

La serialització i la deserialització s’han executat amb èxit

Deserialització : És el procés invers de serialització on es recrea el flux de bytes serialitzats d’un objecte del remitent a l’extrem receptor.

// Deserialitzar

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 ( ) Employee e2 = (Employee) in.readObject () Employee e3 = (Employee) 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 (Excepció e) {System.out.println (e)}}}

Sortida:

20110 Joan
22110 Jerry

20120 Sam

Avantatges i desavantatges de la serialització a Java

Avantatges:

  • El procés de serialització és un incorporat funció que no requereix programari de tercers per executar la serialització
  • S'ha demostrat que és el procediment de serialització simple i fàcil entendre

  • El procediment de serialització és universal i els desenvolupadors de diferents antecedents el coneixen

  • És fàcil d'utilitzar i fàcil de personalitzar

  • Fluxos de dades serialitzats suporta xifratge, compressió i autenticació i informàtica Java segura

  • Hi ha molts tecnologies crítiques basant-se en la serialització.

Desavantatges:

  • Objectes mentre es fa la deserialització fràgil i no estan segurs de ser serialitzats eficaçment.

  • Les variables transitòries declarades mentre la serialització crea espai de memòria, però no s’anomena el constructor, la qual cosa provoca un fracàs en la inicialització de variables transitòries, donant lloc a variació al flux Java estàndard.

  • El procés de serialització és ineficient quant a la utilització de la memòria.

  • No és preferible utilitzar la serialització en les aplicacions que necessitin accés simultani sense el requisit de API de tercers , ja que la serialització no ofereix cap mecanisme de control de transició per cada SE.

  • El procediment de serialització no s'ofereix control de gra fi per accedir a Objectes.

Exemples pràctics de serialització a Java

Serialització mitjançant l'herència

Cas 1: si la superclasse es pot serialitzar, per defecte, les seves subclases també es poden serialitzar.

En aquest cas, el fitxer subclasse es pot serialitzar per defecte si el fitxer superclasse està implementant el fitxer Interfície serialitzable

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}} classe B amplia A {int j public B (int i, int j) {super (i) this.j = j}} prova de classe pública {public static void main (String [] args) llança Excepció {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 = nou ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('L'objecte s'ha serialitzat') FileInputStream fis = nou FileInputStream ('abc.ser') ObjectInputStream ois = nou ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('L'objecte s'ha deserialitzat') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Sortida:

j = 20
L'objecte s'ha serialitzat
L'objecte s'ha deserialitzat
i = 200
j = 400

Cas 2: es pot serialitzar una subclasse si implementa la interfície serialitzable fins i tot si una superclasse no implementa la interfície serializable.

En aquest cas, si el fitxer superclasse no està implementant el fitxer Interfície serialitzable , llavors, els objectes del subclasse es pot serialitzar manualment implementant la interfície serialitzable a la subclasse.

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')}} class subclass extends implements superclass Serializable {int j public subclass (int i, int j) {super (i) this.j = j }} classe pública test2 {public static void main (String [] args) llança Excepció {subclasse b1 = nova subclasse (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 ('L'objecte s'ha serialitzat') FileInputStream fis = new FileInputStream ('output.ser') ObjectInputStream ois = nova ObjectInputStream (fis) subclass b2 = (subclass) ois.readObject ( ) ois.close () fis.close () System.out.println ('L'objecte s'ha deserialitzat') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

L'objecte s'ha serialitzat
Es diu constructor de superclasse
L'objecte s'ha deserialitzat
i = 50
j = 20

què és ide a java

Cas 3: si la superclasse es pot serialitzar, però no necessitem que es serialitzi la subclasse.

En aquest cas, es pot evitar la serialització de la subclasseimplementant el fitxer writeObject () i readObject () mètodes de la subclasse i que ha de llançar NotSerializableException a partir d’aquests mètodes.

package 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}} class child extends Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) llança IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) llança 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 s'ha serialitzat ') FileInputStream fis = new FileInputStream (' abc.ser ') ObjectInputStream ois = new ObjectInputStream (fis) child b2 = (child) ois.readObject () ois.close () fis.close () System.out. println ('L'objecte s'ha deserialitzat') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Sortida:

i = 100
j = 200
Excepció al fil 'principal' java.io.NotSerializableException
a SerializationInheritance.child.writeObject (test3.java:48)
a sun.reflect.NativeMethodAccessorImpl.invoke0 (mètode natiu)

Serialització mitjançant un membre estàtic

La serialització del camp membre estàtic s’ignora en el procés de serialització. La serialització ésrelacionat amb l’últim estat de l’objecte. Per tant, només són les dades associades a una instància específica d’una classeserialitzat però no el camp membre estàtic.

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 ('En el moment de la serialització, El membre estàtic té valor: '+ i) prova {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 ('Després de la deserialització, el membre estàtic té valor:' + i)} catch (Excepció e) {System.out.println (e)}}}

Sortida:

En el moment de la serialització, el membre estàtic té un valor: 100
Després de la deserialització, el membre estàtic té un valor: 99

Interfície externalitzable

El Interfície externalitzable a Java és similar a la serialització, però l'única diferència és que és capaç d'oferir serialització personalitzada on podeu decidir els objectes que s’han de fer malestar al flux.

La interfície externalitzable està disponible a java.io i proporciona dos mètodes:

  • public void writeExternal (ObjectOutput out) llança IOException
  • public void readExternal (ObjectInput in) llança IOException

Les diferències clau entre serialització i externalització són les següents:

  • Implementació : La interfície externalitzable excepte a l'usuari explícitament mencioneu els objectes que s'han de serialitzar. Mentre es troba a la Interfície de serialització, tots els objectes i variables es serialitzen al fitxer temps d'execució.

  • Mètodes : La interfície externalitzable consta de dos mètodes, a saber:

    • writeExternal ()

    • readExternal ()

Mentre que, la interfície serialitzable no inclou cap mètode.

  • Procés: Proporciona el procés de serialització a la interfície externalitzable personalització al procés de serialització. Però, la interfície de serialització proporcionarà el fitxer per defecte procés de serialització.

  • Compatibilitat i control cap enrere: La interfície externalitzable admet la serialització independentment de la control de versions i l’únic problema és que l’usuari ha de ser responsable mentre serialitza Super Class. D 'altra banda, la interfície de serialització requereix mateixa versió de JVM als dos extrems, però incorpora la serialització automàtica de tots els objectes i classes, inclosa la superclasse.

  • Constructor públic sense argument: Necessitats d’interfície d’externalització Constructor públic sense Arg per reconstruir l'objecte serialitzat. Tot i que la interfície de serialització no requereix un constructor No-Arg, en lloc d’això s’utilitza reflexió per reconstruir l'objecte o la classe serialitzats.

package ext import java.io. * Demo class implementa java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} classe 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 ('L'objecte s'ha serialitzat')} catch (IOException ex) {System.out.println ('IOException is caught')} Demo object1 = null prova {FileInputStream file = new FileInputStream (nom del fitxer) ObjectInputStream in = nou ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Object ha estat deserialitzat ') 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 està capturada')}}}

Paraula clau transitòria

La paraula clau transitòria és un paraula clau reservada a Java. S'utilitza com a variable modificable en el moment del procés de serialització. La declaració d'una variable amb paraula clau Transitori evita que la variable es serialitzi.

Versió sèrie UID

Abans que comenci el procés de serialització, cada classe / objecte serialitzable s’associa a un número d'identificació únic proporcionat per la JVM de la màquina amfitrió. Es diu aquest identificador únic Versió sèrie UID . Aquest UID s'utilitza com a identificació per part de la JVM de l'extrem receptor per confirmar que el mateix objecte s'està deserialitzant a l'extrem receptor.

Controvèrsies de serialització a Java

D’Oracle Els arquitectes tenen la intenció d’eliminar la serialització de Java, ja que la consideren com a Horrible error del 1997 . Després d'una investigació agitada, els desenvolupadors d'Oracle van descobrir alguns defectes en el disseny del procediment de serialització que representen una amenaça per a les dades.

L’any 1997,Mark Reinhold afirma: ' Ens agrada anomenar la serialització 'el regal que es continua donant' i el tipus de regal que continua donant són les vulnerabilitats de seguretat. Probablement un terç de totes les vulnerabilitats de Java han implicat la serialització, ja que podria ser més de la meitat. És una font de vulnerabilitats sorprenentment fecunda, per no parlar de les inestabilitats ”.

Hi ha possibilitats que la serialització s’elimini o se substitueixi a les properes actualitzacions de Java i, d’altra banda, per a un principiant a Java, la serialització no podia ser una opció idealista en els seus projectes

Pràctiques recomanades mentre s'utilitza la serialització a Java

A continuació es detallen algunes de les pràctiques recomanades que cal seguir

  • Es recomana l'ús javadoc @ etiqueta sèrie per indicar camps serialitzables.
  • El .Ser es prefereix l'extensió per a fitxers que representen objectes serialitzats.
  • No es recomana que es produeixi cap camp estàtic o transitori serialització per defecte.
  • Classes extensibles no s'ha de serialitzar tret que ho sigui obligatori.
  • Classes interiors s'ha d'evitar que participi en la serialització.

Amb això, hem arribat al final d’aquest article. Espero que hagueu entès els conceptes bàsics de la serialització a Java, els seus tipus i les seves funcionalitats.

Consulteu el per Edureka, una empresa d'aprenentatge en línia de confiança amb una xarxa de més de 250.000 estudiants satisfets repartits per tot el món. El curs de formació i certificació de Java J2EE i SOA d’Edureka està dissenyat per a estudiants i professionals que vulguin ser desenvolupador de Java. El curs està dissenyat per donar-vos un avantatge en la programació de Java i formar-vos tant per a conceptes bàsics com avançats de Java, juntament amb diversos marcs Java com Hibernate i Primavera .

Tens alguna pregunta? Esmenteu-lo a la secció de comentaris d’aquest article de “serialització en Java” i us respondrem el més aviat possible.