Java Language Serializzazione di base in Java


Esempio

Cos'è la serializzazione

La serializzazione è il processo di conversione dello stato di un oggetto (inclusi i suoi riferimenti) in una sequenza di byte, nonché il processo di ricostruzione di quei byte in un oggetto live in un momento futuro. La serializzazione viene utilizzata quando si desidera mantenere l'oggetto. Viene anche utilizzato da Java RMI per passare oggetti tra JVM, come argomenti in un richiamo di metodo da un client a un server o come valori di ritorno da una chiamata di metodo o come eccezioni generate da metodi remoti. In generale, la serializzazione viene utilizzata quando vogliamo che l'oggetto esista oltre la durata della JVM.

java.io.Serializable è un'interfaccia marker (non ha corpo). È appena usato per "contrassegnare" le classi Java come serializzabili.

Il runtime di serializzazione associa a ciascuna classe serializzabile un numero di versione, chiamato serialVersionUID , utilizzato durante la de- serializzazione per verificare che il mittente e il destinatario di un oggetto serializzato abbiano caricato classi per quell'oggetto che sono compatibili con la serializzazione. Se il destinatario ha caricato una classe per l'oggetto che ha un serialVersionUID diverso da quello della classe del mittente corrispondente, la deserializzazione produrrà una InvalidClassException . Una classe serializzabile può dichiarare il proprio serialVersionUID esplicitamente dichiarando un campo denominato serialVersionUID che deve essere static, final, e di tipo long :

ANY-ACCESS-MODIFIER static final long serialVersionUID = 1L;

Come rendere una classe idonea per la serializzazione

Per mantenere un oggetto, la rispettiva classe deve implementare l'interfaccia java.io.Serializable .

import java.io.Serializable;

public class SerialClass implements Serializable {

    private static final long serialVersionUID = 1L;  
    private Date currentTime;
    
    public SerialClass() {
        currentTime = Calendar.getInstance().getTime();
    }

    public Date getCurrentTime() {
        return currentTime;
    }
}

Come scrivere un oggetto in un file

Ora dobbiamo scrivere questo oggetto su un file system. Utilizziamo java.io.ObjectOutputStream per questo scopo.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;

public class PersistSerialClass {

    public static void main(String [] args) {
        String filename = "time.ser";            
        SerialClass time = new SerialClass(); //We will write this object to file system.
        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
            out.writeObject(time); //Write byte stream to file system.
            out.close();
        } catch(IOException ex){
            ex.printStackTrace();
        }
     }
 }

Come ricreare un oggetto dal suo stato serializzato

L'oggetto memorizzato può essere letto dal file system in un secondo momento utilizzando java.io.ObjectInputStream come mostrato di seguito:

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.java.lang.ClassNotFoundException;

 public class ReadSerialClass {

    public static void main(String [] args) {
        String filename = "time.ser";    
        SerialClass time = null;

        try {
            ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
            time = (SerialClass)in.readObject();
            in.close();
        } catch(IOException ex){
            ex.printStackTrace();
        } catch(ClassNotFoundException cnfe){
            cnfe.printStackTrace();
        }
        // print out restored time
        System.out.println("Restored time: " + time.getTime());
     }
 }

La classe serializzata è in forma binaria. La deserializzazione può essere problematica se la definizione della classe cambia: consultare il capitolo sul controllo delle versioni degli oggetti serializzati della specifica di serializzazione Java per i dettagli.

La serializzazione di un oggetto serializza l'intero grafico dell'oggetto di cui è la radice e opera correttamente in presenza di grafici ciclici. Viene fornito un metodo reset() per forzare ObjectOutputStream a dimenticare gli oggetti che sono già stati serializzati.

Campi transitori - Serializzazione