En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Disseny de la persistènciaSerialització
Toni Navarrete
Enginyeria del Software II – UPF 2007
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 2
Serialització
• És la forma que té Java per fer permanents els objectes (per guardar-los a disc)
• 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 buidapackage java.io; public interface Serializable {
// no hi ha res aquí!!};
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 3
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)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 4
Serialització
• Escriure un objecte en un Object Stream. Example:
FileOutputStream out = new FileOutputStream(“nomFitxer");
ObjectOutputStream s = new ObjectOutputStream(out);
s.writeObject(objecte);
s.flush();
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 5
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"); }
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 6 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); try { color.guardaObjecte(); color.recuperaObjecte(); } catch(Exception e) { System.out.println("Error d'E/S"); System.exit(0); } }}
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 7
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
• Llegeix la tira de bits emmagatzemats amb writeExternal 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 què hem guardat els atributs determina l’ordre per recuperar-los
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 8
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
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
Pàgina 9
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)• Persistència transitiva
• Inconvenients:– No té les característiques d’un gestor de BD
robust• Per exemple, índexs
– No és escalable