Serializzazione
Per serializzazione si intende la trasformazione di un oggetto java in uno stream di byte.
La deseralizzazione, invece, è la trasformazione di uno stream di byte in oggetti java. Queste operazioni vengono, ad esempio, effettuate quando si invoca un metodo, che prende in input un oggetto, che si trova su una macchina remota (quindi con diversa JVM) o durante la lettura/scrittura di un file binario.
Per rendere una classe serializzabile è sufficiente implementare la classe Serializable e definire il serialversionUID:
Esempio:
public class PersistentTime implements Serializable { private static final long serialVersionUID = 1L; ……
InvalidClassException
In genere, quando si apportano modifiche consistenti ad una classe serializzabile (ad esempio, si cambia il tipo di uno o più attributi) il valore di serialUID deve essere ricalcolato/cambiato, ad indicare che la classe è diversa da quella originaria (in genere si incrementa di 1 per indicare una vesione subito successiva di quella classe).
Dopo la modifica, il tentativo di leggere dati serializzati con la “vecchia versione” della classe genera eccezioni di tipo “InvalidClassException”.
Per questi motivi è fortemente consigliato assegnare un valore esplicito alla suddetta costante. Questa assegnazione può essere fatta a mano o può essere fatto calcolare dalla JVM durante la scrittura del codice sorgente.
Nel caso di serialUID non specificato, la JVM che fa la serializzazione ne assegna uno di default (calcolato con un suo algoritmo).
La JVM che deserializza a sua volta usa un suo algoritmo per crearlo e potrebbe essere diverso da dalla JVM di origine, generando cosi eccezione.
Esempio
package example.serializzazione; import java.io.Serializable; public class Address implements Serializable{ /** * */ private static final long serialVersionUID = 2L; /** * */ //test //private static final long serialVersionUID = 2L; String street; String country; String prova; public void setStreet(String street){ this.street = street; } public void setCountry(String country){ this.country = country; } public String getStreet(){ return this.street; } public String getCountry(){ return this.country; } @Override public String toString() { return new StringBuffer(" Street : ") .append(this.street) .append(" Country : ") .append(this.country).toString(); } }
Creiamo una classe che scrive una serie di oggetti di tipo Address dentro un file address.ser
import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class WriteObject { public static void main (String args[]) { Address address = new Address(); address.setStreet("wall street"); address.setCountry("united states"); try{ FileOutputStream fout = new FileOut-putStream("c:\\prova\\address.ser"); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(address); oos.close(); System.out.println("Done"); }catch(Exception ex){ ex.printStackTrace(); } } }
Leggiamo il file address.ser tramite la classe ReadObject
package example.serializzazione; import java.io.FileInputStream; import java.io.ObjectInputStream; public class ReadObject { public static void main (String args[]) { Address address; try{ FileInputStream fin = new FileInputStream("c:\\prova\\address.ser"); ObjectInputStream ois = new ObjectInputStream(fin); address = (Address) ois.readObject(); ois.close(); System.out.println(address); }catch(Exception ex){ ex.printStackTrace(); } } }
L’output prodotto è:
Street : wall street Country : united states
Se modifichiamo il serialUid di address
package example.serializzazione; import java.io.Serializable; public class Address implements Serializable{ /** * */ private static final long serialVersionUID = 3L; /** * */ //test //private static final long serialVersionUID = 2L; String street; String country; String prova; public void setStreet(String street){ this.street = street; } public void setCountry(String country){ this.country = country; } public String getStreet(){ return this.street; } public String getCountry(){ return this.country; } @Override public String toString() { return new StringBuffer(" Street : ") .append(this.street) .append(" Country : ") .append(this.country).toString(); } }
Se proviamo a rileggere ora il file, tramite la classe ReadObject, viene lanciata l’eccezione InvalidClassException
Video Lezione Serializzazione e Deserializzazione