Disseny de la persistència Serialització Toni Navarrete Enginyeria del Software II – UPF 2005
Serialització És la forma que té Java per fer permanents els objectes (per guardar-los) Serialització s’usa típicament en RMI per enviar objectes. També com a “persistència light” Les classes dels objectes que es vulguin fer persistents han d’implementar la interfície Serializable Aquesta interfície és buida package java.io; public interface Serializable { // no hi ha res aquí!! };
Serialització Què es guarda d’un objecte quan es serialitza? Tots els atributs que no siguin static (perquè són atributs de la classe i no de la instància) transient (indica que no s’ha de serialitzar). Per exemple, atributs que es poden calcular a partir d’altres atributs, atributs confidencials ... Encara que sigui private se serialitza (compte!) Referències a altres objectes... Es guarden els objectes referenciats i la seva referència Per poder-los recuperar cal que també siguin serialitzables (que la seva classe implementi Serializable)
Escriure un objecte en un Object Stream. Example: Serialització Escriure un objecte en un Object Stream. Example: FileOutputStream out = new FileOutputStream(“nomFitxer"); ObjectOutputStream s = new ObjectOutputStream(out); s.writeObject(objecte); s.flush();
Recuperar un objecte des d’un Object Stream. Exemple Serialització Recuperar un objecte des d’un Object Stream. Exemple FileInputStream in = new FileInputStream("nomFitxer"); ObjectInputStream s = new ObjectInputStream(in); try { Color c = (Color)s.readObject(); System.out.println("R: " + c.R); System.out.println("G: " + c.G); System.out.println("B: " + c.B); } catch(ClassNotFoundException cnfe) { System.out.println("Excepció classe no definida"); }
Serialització. Un exemple complet import java.io.*; public class ColorRGB implements Serializable { int R,G,B; public ColorRGB(int R, int G, int B) { this.R = R; this.G = G; this.B = B; } void guardaObjecte() throws FileNotFoundException, IOException { FileOutputStream out = new FileOutputStream("ObjecteColor"); ObjectOutputStream s = new ObjectOutputStream(out); s.writeObject(this); s.flush(); void recuperaObjecte() throws FileNotFoundException, IOException { FileInputStream in = new FileInputStream("ObjecteColor"); ObjectInputStream s = new ObjectInputStream(in); try { ColorRGB c = (ColorRGB)s.readObject(); System.out.println("R: " + c.R); System.out.println("G: " + c.G); System.out.println("B: " + c.B); } catch(ClassNotFoundException cnfe) { System.out.println("Excepció classe no definida"); public static void main(String[] args) { ColorRGB color = new ColorRGB(0,0,255); color.guardaObjecte(); color.recuperaObjecte(); } catch(Exception e) { System.out.println("Error d'E/S"); System.exit(0);
Serialització amb Externalizable Hi ha una altra inferfície que ens permet un major control de què se serialitza: Externalizable 2 mètodes per personalitzar el comportament quan se serialitza: public void writeExternal(ObjectOutput out) throws IOException Només es guarden els atributs que aquí s’especifiquin public void readExternal(ObjectInput in) throws IOException No llegeix tota la tira de bits emmagatzemats i recupera l’objecte Crida al constructor per defecte i recupera els atributs especificats aquí El constructor per defecte (buit) ha de ser públic Nota: L’ordre en que hem guardat els atributs determina l’ordre per recuperar-los
Serialització amb Externalizable. Un exemple complet import java.io.*; public class ColorRGB1 implements Externalizable { int R,G,B; public ColorRGB1() { } public ColorRGB1(int R, int G, int B) { this.R = R; this.G = G; this.B = B; } public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(R); out.writeInt(B); //si fos un tipus no primitiu (per exemple String o una classe pròpia de l’aplicació) es faria amb writeObject public void readExternal(ObjectInput in) throws IOException { R = in.readInt(); B = in.readInt(); //si fos un tipus no primitiu (per exemple String o una class pròpia de l’aplicació) es faria amb readObject public static void main(String[] args) throws IOException, FileNotFoundException, ClassNotFoundException{ ColorRGB1 color = new ColorRGB1(100,200,255); FileOutputStream out = new FileOutputStream("ObjecteColor"); ObjectOutputStream sout = new ObjectOutputStream(out); sout.writeObject(color); sout.close(); FileInputStream in = new FileInputStream("ObjecteColor"); ObjectInputStream sin = new ObjectInputStream(in); ColorRGB1 c = (ColorRGB1)sin.readObject(); System.out.println("R: "+ c.R); System.out.println("G: "+ c.G); System.out.println("B: "+ c.B); Serialització amb Externalizable. Un exemple complet
Avantatges i inconvenients de la serialització Avantantges: Estàndard en qualsevol ambient Java Fàcil d’utilitzar El model de dades és directament el de les classes (aprofita OO) Inconvenients: No té les característiques d’un gestor de BD robust Per exemple, índexs No és escalable