Qual è il concetto di serializzazione in Java?



Questo articolo aiuterà con un approccio completo al concetto di serializzazione in Java insieme ad esempi in tempo reale per una migliore comprensione.

Serializzazione in è un concetto importante che si occupa della conversione di oggetti in un flusso di byte per trasportare gli oggetti java da una Java Virtual Machine all'altra e ricrearli nella forma originale. Allineerò il docket per questo articolo come di seguito:

Cos'è la serializzazione in Java?

Serializzazione in Java è il processo di conversione del codice Java Oggetto in un Byte Stream , per trasferire il codice oggetto da una Java Virtual machine a un'altra e ricrearlo utilizzando il processo di Deserializzazione.





Serialization-in-Java-Edureka-Picture-1

Perché abbiamo bisogno della serializzazione in Java ?

Abbiamo bisogno della serializzazione per i seguenti motivi:



  • Comunicazione : La serializzazione implica la procedura dell'oggetto serializzazione e trasmissione. Ciò consente a più sistemi di computer di progettare, condividere ed eseguire oggetti contemporaneamente.

  • Caching : Il tempo impiegato per la creazione di un oggetto è maggiore rispetto al tempo necessario per deserializzarlo. La serializzazione riduce al minimo il consumo di tempo di caching gli oggetti giganti.

  • Copia profonda : Clonazione Il processo è reso semplice utilizzando la serializzazione. Un esatto replica di un oggetto è ottenuto daserializzare l'oggetto in un file matrice di byte e quindi de-serializzarlo.



  • Attraversare Sincronizzazione JVM: Il vantaggio principale della serializzazione è chefunziona su JVM differenti che potrebbero essere in esecuzione su differenti architetture o Sistemi operativi

  • Persistenza: Lo stato di qualsiasi oggetto può essere archiviato direttamente applicandovi la serializzazione e archiviato in un file Banca dati in modo che possa essere recuperato in seguito.

Come serializziamo un oggetto?

PER Oggetto Java è serializzabile se e solo se la sua classe o una delle sue classi genitore implementa il Giava . io . Serializzabile interfaccia o la sua sottointerfaccia, java.io.Externalizable.

codice java per terminare il programma

Nel processo di serializzazione, convertiamo lo stato di un oggetto in un flusso di byte in modo che possa essere trasferito da una JVM all'altra e ripristiniamo il flusso di byte nell'oggetto originale.

//Interfaccia

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

// Serializza

pacchetto 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 ('Serializzazione e deserializzazione sono state eseguite con successo')} catch (Eccezione e) {System.out.println (e)}}}

Produzione:

La serializzazione e la deserializzazione sono state eseguite correttamente

Deserializzazione : È il processo inverso della serializzazione in cui il flusso di byte serializzato di un oggetto dal mittente viene ricreato all'estremità ricevente.

// Deserializzare

pacchetto 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 (eccezione e) {System.out.println (e)}}}

Produzione:

20110 Giovanni
22110 Jerry

20120 Sam

Vantaggi e svantaggi della serializzazione in Java

Vantaggi:

  • Il processo di serializzazione è un file incorporato funzionalità che non richiede software di terze parti per eseguire la serializzazione
  • La procedura di serializzazione ha dimostrato di essere semplice e facile capire

  • La procedura di serializzazione è universale e gli sviluppatori con background diversi lo conoscono

  • È facile da usare e semplice da personalizzare

  • Flussi di dati serializzati supporta crittografia, compressione, autenticazione e elaborazione sicura di Java

  • Ci sono molti tecnologie critiche basandosi sulla serializzazione.

Svantaggi:

  • Oggetti mentre la deserializzazione diventa fragile e non è sicuro che vengano deSerializzati in modo efficace.

  • Le variabili transitorie dichiarate durante la serializzazione creano spazio di memoria, ma non viene chiamato il costruttore, il che si traduce in un errore nell'inizializzazione delle variabili transitorie con conseguente variazione allo Standard Java Flow.

  • Il processo di serializzazione è inefficiente in termini di utilizzo della memoria.

  • La serializzazione non è preferibile per le applicazioni che necessitano accesso simultaneo senza il requisito di API di terze parti , poiché la serializzazione non offre alcun meccanismo di controllo della transizione per ogni SE.

  • La procedura di serializzazione non riesce a offrire controllo a grana fine per accedere agli oggetti.

Esempi pratici di serializzazione in Java

Serializzazione tramite ereditarietà

Caso - 1: se la Superclass è serializzabile, per impostazione predefinita anche le sue sottoclassi sono serializzabili.

In questo caso, il file sottoclasse è serializzabile per impostazione predefinita se il file superclasse sta implementando il Interfaccia serializzabile

package SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable classe A implementa Serializable {int i public A (int i) {this.i = i}} la classe B estende 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 = nuovo B (200,400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = nuovo FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('L'oggetto è stato serializzato') FileInputStream fis = new FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('L'oggetto è stato deserializzato') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Produzione:

j = 20
L'oggetto è stato serializzato
L'oggetto è stato deserializzato
io = 200
j = 400

Caso - 2: una sottoclasse può essere serializzata se implementa l'interfaccia serializzabile anche se una superclasse non implementa l'interfaccia serializzabile.

In questo caso, se il file superclasse non sta implementando il Interfaccia serializzabile , quindi, gli oggetti di sottoclasse può essere serializzato manualmente implementando l'interfaccia Serializable nella sottoclasse.

pacchetto SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable classe superclasse {int i public superclass (int i) {this.i = i} public superclass () {i = 50 System.out.println ('Superclass constructor called')}} class subclass extends superclass implements Serializable {int j public subclass (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) genera Eccezione {subclass b1 = new subclass (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'oggetto è stato serializzato') FileInputStream fis = new FileInputStream ('output.ser') ObjectInputStream ois = new ObjectInputStream (fis) sottoclasse b2 = (sottoclasse) ois.readObject ( ) ois.close () fis.close () System.out.println ('L'oggetto è stato deserializzato') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

L'oggetto è stato serializzato
Costruttore di superclasse chiamato
L'oggetto è stato deserializzato
io = 50
j = 20

Caso - 3: se la superclasse è serializzabile, ma non è necessario serializzare la sottoclasse.

In questo caso, è possibile impedire la serializzazione della sottoclasseimplementando il writeObject () e readObject () metodi nella sottoclasse e deve lanciare NotSerializableException da questi metodi.

pacchetto 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 Parent implements 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) throws 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 è stato serializzato ') FileInputStream fis = new FileInputStream (' abc.ser ') ObjectInputStream ois = nuovo ObjectInputStream (fis) figlio b2 = (figlio) ois.readObject () ois.close () fis.close () System.out. println ('L'oggetto è stato deserializzato') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Produzione:

io = 100
j = 200
Eccezione nel thread 'main' java.io.NotSerializableException
in SerializationInheritance.child.writeObject (test3.java:48)
su sun.reflect.NativeMethodAccessorImpl.invoke0 (metodo nativo)

Serializzazione tramite un membro statico

La serializzazione del campo membro statico viene ignorata nel processo di serializzazione. La serializzazione èrelativo all'ultimo stato dell'oggetto. Quindi, solo i dati associati a un'istanza specifica di una classe sonoserializzato ma non il campo del membro statico.

pacchetto stati import java.io. * class StaticSerial implementa Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('Al momento della serializzazione, membro statico ha valore: '+ 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 ('After Deserialization, static member has value:' + i)} catch (eccezione e) {System.out.println (e)}}}

Produzione:

Al momento della serializzazione, il membro statico ha valore: 100
Dopo la deserializzazione, il membro statico ha il valore: 99

Interfaccia esternalizzabile

Il Interfaccia esternalizzabile in Java è simile alla serializzazione ma l'unica differenza è che è in grado di offrire serializzazione personalizzata dove si arriva a decidere gli oggetti da rimuovere nel flusso.

L'interfaccia Externalizable è disponibile in java.io e fornisce due metodi:

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

Le differenze principali tra serializzazione ed esternalizzabile sono le seguenti:

  • Implementazione : Interfaccia esternalizzabile tranne che per l'utente esplicitamente menzionare gli oggetti da serializzare. Mentre ci si trova nell'interfaccia di serializzazione, tutti gli oggetti e le variabili vengono serializzati nel file tempo di esecuzione.

  • Metodi : L'interfaccia esternalizzabile consiste di due metodi, ovvero:

    • writeExternal ()

    • readExternal ()

Considerando che l'interfaccia serializzabile non include alcun metodo.

convertire double in int in java

  • Processi: Fornisce il processo di serializzazione nell'interfaccia esternalizzabile personalizzazione al processo di serializzazione. Ma l'interfaccia di serializzazione fornirà l'estensione predefinito processo di serializzazione.

  • Compatibilità e controllo all'indietro: L'interfaccia esternalizzabile supporta la serializzazione indipendentemente da controllo della versione e l'unico problema è che l'utente deve essere responsabile durante la serializzazione di Super Class. D'altra parte, l'interfaccia di serializzazione richiede l'estensione stessa versione di JVM su entrambe le estremità, ma incorpora la serializzazione automatica di tutti gli oggetti e le classi inclusa la superclasse.

  • Costruttore pubblico No-Arg: Esigenze dell'interfaccia di esternalizzazione Costruttore pubblico No-Arg per ricostruire l'oggetto serializzato. Sebbene l'interfaccia di serializzazione non richieda il costruttore No-Arg, utilizza invece riflessione per ricostruire l'oggetto o la classe serializzata.

pacchetto ext import java.io. * class Demo implementa 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 ('Object has been serialized')} catch (IOException ex) {System.out.println ('IOException is catch')} Demo object1 = null try {FileInputStream file = new FileInputStream (filename) ObjectInputStream in = new ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Object has been deserializzato ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException is catch ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException è stata rilevata')}}}

Parola chiave transitoria

La parola chiave transitoria è un file parola chiave riservata in Java. È usato come file modifica variabile al momento del processo di serializzazione. La dichiarazione di una variabile con la parola chiave Transient evita che la variabile venga serializzata.

UID versione seriale

Prima che il processo di serializzazione inizi, ogni classe / oggetto serializzabile viene associato a un file numero di identificazione univoco fornito dalla JVM della macchina host. Questo ID univoco viene chiamato UID versione seriale . Questo UID viene utilizzato come identificazione dalla JVM dell'estremità ricevente per confermare che lo stesso oggetto viene deSerializzato all'estremità ricevente.

Controversie sulla serializzazione in Java

Oracle Gli architetti intendono rimuovere la serializzazione da Java poiché lo considerano come un file Orribile errore del 1997 . Dopo una ricerca frenetica, gli sviluppatori di Oracle hanno scoperto alcuni difetti nella progettazione della procedura di serializzazione che rappresentano una minaccia per i dati.

Nell'anno 1997,Mark Reinhold afferma: ' Ci piace chiamare la serializzazione 'il regalo che continua a fare' e il tipo di regalo che continua a offrire sono le vulnerabilità della sicurezza. Probabilmente un terzo di tutte le vulnerabilità di Java ha coinvolto la serializzazione, potrebbe essere più della metà. È una fonte sorprendentemente feconda di vulnerabilità, per non parlare delle instabilità ”.

Ci sono possibilità che la serializzazione venga rimossa o sostituita nei prossimi aggiornamenti di Java e d'altra parte, per un principiante in Java, la serializzazione non poteva essere un'opzione idealistica nei loro progetti

Best practice durante l'utilizzo della serializzazione in Java

Di seguito sono riportate alcune best practice che devono essere seguite

  • Si consiglia l'utilizzo javadoc @ tag seriale per indicare i campi serializzabili.
  • Il .essere è preferibile utilizzare l'estensione per i file che rappresentano oggetti serializzati.
  • Si sconsiglia di subire campi statici o transitori serializzazione predefinita.
  • Classi estendibili non dovrebbe essere serializzato a meno che non lo sia obbligatorio.
  • Classi interne dovrebbe essere evitato di essere coinvolti nella serializzazione.

Con questo, siamo arrivati ​​alla fine di questo articolo. Spero che tu abbia compreso le basi della serializzazione in Java, i suoi tipi e le sue funzionalità.

Controlla il da Edureka, una società di formazione online affidabile con una rete di oltre 250.000 studenti soddisfatti sparsi in tutto il mondo. Il corso di formazione e certificazione Java J2EE e SOA di Edureka è progettato per studenti e professionisti che desiderano diventare sviluppatori Java. Il corso è progettato per darti un vantaggio nella programmazione Java e formarti per concetti Java sia di base che avanzati insieme a vari framework Java come Hibernate & Primavera .

Hai domande per noi? Menzionalo nella sezione commenti di questo articolo 'Serializzazione in Java' e ti risponderemo il prima possibile.