Come serializzare gli oggetti

Da Head First Java O'Reilly, capitolo 14.

In Java un oggetto può essere reso persistente per mezzo del meccanismo della serializzazione che, in pratica, consiste nel salvare lo stato dell'oggetto in qualche modo su una qualche periferica.

Per default una classe non é serializzabile. Bisogna implementare l'interfaccia Serializable. Non esiste alcun metodo in questa interfaccia, é utilizzata semplicemente come etichetta per indicare che siamo consapevoli che un oggetto di questa classe possa essere serializzato.

Il senso della cosa é che se per qualche motivo non vogliamo che oggetti di quella classe vengano resi persistenti abbiamo un mezzo per farlo (non implementando l'interfaccia).

Non é necessario implementare esplicitamente Serializable, é sufficiente che la nostra classe derivi da una classe che implementa questa interfaccia.

Cercare di serializzare un oggetto non serializzabile, anche solo in una sua componente, causa una eccezione di tipo java.io.NotSerializableException, ma é possibile esclude esplicitamente le componenti che non si vogliono serializzare.

Per compiere il processo ci si appoggia su due stream. Il primo si occupa della serializzazione vera e propria (traduce l'oggetto in una sequenza di byte), il secondo si occupa dei dettagli di basso livello per quanto riguarda la persistenza dello stream che gli viene passato.

Quello che facciamo nell'esempio che segue é creare un oggetto FileOutputStream, che si occupa di gestire il file, e un oggetto ObjectOutputStream che si occupa della serializzazione e usa il FileOutputStream per scrivere effettivamente su file.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Box implements Serializable {
private int x;
private int y;
private transient InnerStuff stuff;

private class InnerStuff {
public InnerStuff(int internalCode) {
this.internalCode = internalCode;
}
private int internalCode;
}

public Box(int x, int y) {
this.x = x;
this.y = y;
this.stuff = new InnerStuff((int) (Math.random() * 1000));
}

public static void main(String[] args) {
Box box = new Box(12, 42);
try {
FileOutputStream fos = new FileOutputStream("box.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(box);
oos.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}

La classe serializzabile Box ha due variabili di istanza di tipo primitivo (e quindi serializzabili) e un oggetto di tipo InnerStuff (classe che non implementando Serializable non é serializzabile). Se non specificassimo che l'oggetto InnerStuff sia transiente la serializzazione di Box fallirebbe con una eccezione.

Nessun commento:

Posta un commento