You are on page 1of 23

Serializarea obiectelor • Ce este serializarea ?

• Serializarea tipurilor primitive • Serializarea obiectelor • ObjectInputStream ObjectOutputStream • Interfat ¸a Serializable • Controlul serializ˘ arii • Personalizarea serializ˘ arii • Clonarea obiectelor

1

Ce este serializarea ? Serializare= transformarea unui obiect ˆ ıntr-o secvent ¸˘ a de octet ¸i, din care s˘ a poat˘ a fi ref˘ acut ulterior obiectul original. Procesul invers, de citire a unui obiect serializat pentru a-i reface starea original˘ a, se nume¸ ste deserializare. Referint ¸ele care construiesc starea unui obiect formeaz˘ a oˆ ıntreag˘ a ret ¸ea de obiecte. • DataOutputStream, DataInputStream • ObjectOutputStream, ObjectInputStream

2

3 .asigurarea persistent ¸ei componentelor. • Persistent ¸a obiectelor • Compensarea diferent ¸elor ˆ ıntre sisteme de operare • Transmiterea datelor ˆ ın ret ¸ea • RMI (Remote Method Invocation) • Java Beans .Utilitatea serializ˘ arii • Mecanism simplu de utilizat pentru salvarea ¸ si restaurarea datelor.

fos. .writeBoolean(true).Serializarea tipurilor primitive DataOutputStream. out.readBoolean().writeDouble(12. double d = in. boolean b = in. DataInputStream in = new DataInputStream(fis). out. out. 4 . DataInputStream //Scriere FileOutputStream fos = new FileOutputStream("test.close().writeUTF("Sir de caractere"). out.readDouble(). int i = in. fis. String s = in.readInt().flush().345)..dat")..writeInt(12345).dat").close(). out.readUTF(). //Citire FileInputStream fis = new FileInputStream("test. DataOutputStream out = new DataOutputStream(fos).

pentru restaurare. • Signatura clasei. Acesta este un proces recursiv. pentru scriere ¸ si • readObject.Serializarea obiectelor • ObjectOutputStream • ObjectInputStream Mecanismul implicit va salva: • Numele clasei obiectului. de serializare a obiectelor referite (”ret ¸eaua de obiecte”). • Valorile tuturor cˆ ampurile serializabile. 5 . Metode: • writeObject.

345).flush(). FileOutputStream fos = new FileOutputStream("test. out.writeObject("Ora curenta:"). out.Clasa ObjectOutputStream ObjectOutputStream out = new ObjectOutputStream(fluxPrimitiv). out. out.writeObject(new Date()). ObjectOutputStream out = new ObjectOutputStream(fos). NotSerializableException. out. InvalidClassException. fluxPrimitiv. out.close(). out. fos.ser"). Except ¸ii: IOException. out. out. 6 .close().flush().writeInt(12345).writeBoolean(true).writeDouble(12.writeUTF("Sir de caractere").writeObject(referintaObiect).

readUTF().ser"). String s = in.Clasa ObjectInputStream ObjectInputStream in = new ObjectInputStream(fluxPrimitiv). fluxPrimitiv.readInt().close(). fis. 7 . ObjectInputStream in = new ObjectInputStream(fis).readObject(). Date data = (Date)in. double d = in.readBoolean(). boolean b = in.readObject().readDouble(). int i = in.readObject(). FileInputStream fis = new FileInputStream("test.readObject(). String mesaj = (String)in. //sau TipReferinta ref = (TipReferinta)in.close(). Object obj = in.

public interface Serializable { // Nimic ! } public class ClasaSerializabila implements Serializable { // Corpul clasei } 8 .Interfat ¸a Serializable Un obiect este serializabil ⇔ clasa din care face parte implementeaz˘ a interfat ¸a Serializable.io. Interfat ¸a este declarativ˘ a. definit ¸ia ei fiind: package java.

// Participa la serializare 9 . // Ignorata la serializare Modificatorul static anuleaz˘ a efectul modificatorului transient static transient int N.Controlul serializ˘ arii Modificatorul transient transient private double temp.

static int t =4. public class Test1 implements Serializable { int x =1. transient static int z =3. " + y + " . " + z + " . " + t . // DA // NU // DA // DA public String toString () { return x + " . transient int y =2. } } 10 . io .*.Listing 1: Modificatorii static ¸ si transient import java .

*. // Exceptie B b = new B () . x + " . y . // DA public String toString () { return a . class A { int x =1. } public class Test2 implements Serializable { A a = new A () . Listing 2: Membrii neserializabili import java . io . " + b . dac˘ a esteˆ ıntˆ alnit un obiect care nu implementeaz˘ a interfat ¸a Serializable atunci va fi generat˘ ao except ¸ie de tipul NotSerializableException ce va identifica respectiva clas˘ a neserializabil˘ a. } class B implements Serializable { int y =2.Membrii neserializabili In procesul serializ˘ arii. } } 11 .

*. // DA } public String toString () { return x + " . } } 12 .Serializarea cˆ ampurilor mo¸ stenite Listing 3: Serializarea cˆ ampurilor mo¸ stenite import java . " + y . } public class Test3 extends D { public Test3 () { x = 1. // NU y = 2. class C { int x =0. // Obligatoriu constructor fara argumente } class D extends C implements Serializable { int y =0. io .

try { test ( new Test2 () ) . } } 13 .Listing 4: Testarea serializ˘ arii import java . public class Exemplu { public static void test ( Object obj ) throws IOException { // Salvam FileOutputStream fos = new FileOutputStream ( " fisier . writeObject ( obj ) . readObject () . println ( " A fost restaurat obiectul : " + obj ) . out . ObjectInputStream in = new Obje ctInput Stream ( fis ) . out . flush () . } catch ( Cl as sNo tF oun d E x c e p t i o n e ) { e . out . out . fos . ser " ) . } test ( new Test3 () ) . ser " ) . println ( " Obiect neserializabil : " + e ) . io . System . } fis . println ( " A fost salvat obiectul : " + obj ) . try { obj = in . printStackTrace () . ObjectOutputStream out = new Ob je ct Ou tp utS tr ea m ( fos ) . } public static void main ( String args []) throws IOException { test ( new Test1 () ) . out . // Restauram FileInputStream fis = new FileInputStream ( " fisier . close () .*. close () . } catch ( N o t Se r i a li z a b l e E x c e p t i o n e ) { System . System .

defaultWriteObject(). etc. etc.Personalizarea serializ˘ arii Dezavantajele mecanismului implicit: • lent • reprezentarea voluminoas˘ a Personalizarea serializarii: private void writeObject(ObjectOutputStream stream) throws IOException { // Procesarea campurilor clasei (criptare.defaultReadObject().) // Scrierea obiectului curent stream.ClassNotFoundException { // Restaurarea obiectului curent stream.) // si extragerea informatiilor suplimentare } 14 . // Actualizarea starii obiectului (decriptare. // Adaugarea altor informatii suplimentare } private void readObject(ObjectInputStream stream) throws IOException.

*. parola = parola .Controlul versiunilor claselor Listing 5: Prima variant˘ a a clasei Angajat import java . nume = nume . String parola ) { this . class Angajat implements Serializable { public String nume . salariu = salariu . private String parola . } public String toString () { return nume + " ( " + salariu + " ) " . int salariu . public Angajat ( String nume . } } 15 . public int salariu . io . this . this .

println ( " Lista angajatilor :\ n " + ang ) . out .. import java .*. in ) ) .*. printStackTrace () . out . public class GestiuneAngajati { // Lista angajatilor ArrayList ang = new ArrayList () . while ( true ) { System . System . readLine () ) .Listing 6: Aplicat ¸ia de gestionare a angajat ¸ilor import java . ser " ) . " ) . close () . ObjectInputStream in = new Obje ctInput Stream ( fis ) . } public void salvare () throws IOException { FileOutputStream fos = new FileOutputStream ( " angajati . util .. print ( " \ nNume : " ) . } catch ( File NotFo und E x c e p t i o n e ) { System . println ( " Fisierul nou . } System . readLine () .. readObject () . " ) . e . } finally { if ( fis != null ) fis . ang = ( ArrayList ) in . io . } catch ( Exception e ) { System . String nume = stdin . out . print ( " Salariu : " ) . public void citire () throws IOException { FileInputStream fis = null . writeObject ( ang ) . int salariu = Integer . 16 . parseInt ( stdin . try { fis = new FileInputStream ( " angajati . out . ObjectOutputStream out = new Ob je ct Ou tp utS tr ea m ( fos ) . ser " ) . out .. } public void adaugare () throws IOException { BufferedReader stdin = new BufferedReader ( new InputStreamReader ( System . println ( " Eroare la citirea datelor . out .

add ( new Angajat ( nume . System . parola ) ) . // Salvam angajatii inapoi fisier app . if ( raspuns . // Incarcam angajatii din fisier app . String parola = stdin . String raspuns = stdin . } } Ad˘ aug˘ am un nou cˆ amp: adresa. salariu . readLine () . ang . } } public static void main ( String args []) throws IOException { GestiuneAngajati app = new GestiuneAngajati () .System . adaugare () . startsWith ( " N " ) ) break . print ( " Mai adaugati ? ( D / N ) " ) . salvare () . // Adaugam noi angajati app . out . out . citire () . print ( " Parola : " ) . toUpperCase () . Problema: InvalidClassException 17 . readLine () .

serialVersionUID • num˘ ar pe 64 de bit ¸i • generat ˆ ın procesul de serializare/deserializare • salvat ˆ ımpreun˘ a cu starea obiectului • codific˘ a signatura unei clase • ”sensibil” la orice modificare a clasei Setarea explicit˘ a: static final long serialVersionUID = /* numar_serial_clasa */. Utilitarul serialVer permite generarea num˘ arului serialVersionUID 18 .

this . io . adresa = " Iasi " . this . salariu = salariu . parola = parola . } } 19 . private String parola . public String nume .*. adresa . class Angajat implements Serializable { static final long serialVersionUID = 5 6 5 34 9 3 24 8 68 0 6 65 2 9 7 L . this . String parola ) { this . } public String toString () { return nume + " ( " + salariu + " ) " . public Angajat ( String nume . int salariu .Listing 7: Variant˘ a compatibil˘ a a clasei Angajat import java . public int salariu . nume = nume .

for ( int n =0. adresa = " Iasi " . stream .*. n ++) sb . io . int offset ) { StringBuffer sb = new StringBuffer () . int salariu . return sb . n < input . toString () . -3) . this . } public String toString () { return nume + " ( " + salariu + " ) " . class Angajat implements Serializable { static final long serialVersionUID = 5 6 5 34 9 3 24 8 68 0 6 65 2 9 7 L . parola = criptare ( parola . public String nume . } } 20 . this . append (( char ) ( offset + input . defaultWriteObje ct () . public int salariu . parola = parola . parola = criptare ( parola . } private void readObject ( O bjectIn putStre am stream ) throws IOException . C l a s s N o t F o u n d E x c e p t i o n { stream . this . -3) . adresa . public Angajat ( String nume . } private void writeObject ( Ob ject Outpu tStr eam stream ) throws IOException { parola = criptare ( parola . private String parola . String parola ) { this . nume = nume . 3) .Listing 8: Varianta securizat˘ a a clasei Angajat import java . salariu = salariu . defaultReadObject () . charAt ( n ) ) ) . } static String criptare ( String input . length () .

public interface Externalizable extends Serializable { public void writeExternal(ObjectOutput out) throws IOException. public void readExternal(ObjectInput in) throws IOException. ClassNotFoundException. } Scop: cre¸ sterea vitezei procesului de serializare.Interfat ¸a Externalizable Control complet. Definit ¸ia interfet ¸ei Externalizable: package java. explicit al procesului de serializare.io. 21 .

} public void writeExternal ( ObjectOutput s ) throws IOException { s . class Persoana implements Externalizable { int cod . IOException { nume = s . readUTF () . writeInt ( cod ) . io . s . String nume . cod = s . public Persoana ( String nume .*. } } Listing 10: Serializare proprie import java .*. String nume . readInt () . class Persoana implements Serializable { int cod . } public void readExternal ( ObjectInput s ) throws ClassNotFoundException . this . nume = nume . nume = nume . this . io . public Persoana ( String nume . writeUTF ( nume ) . cod = cod . int cod ) { this .Listing 9: Serializare implicit˘ a import java . cod = cod . } } 22 . int cod ) { this .

out.readObject(). } } 23 . ObjectInputStream in = new ObjectInputStream(bais). out. ByteArrayInputStream bais = new ByteArrayInputStream(buffer).clone().writeObject(this). } catch (Exception e) { return null.Clonarea obiectelor TipReferinta o1 = new TipReferinta().close(). Object ret = in. return ret.toByteArray(). ObjectOutputStream out = new ObjectOutputStream(baos). in.close(). byte[] buffer = baos. TipReferinta o2 = (TipReferinta) o1. public Object clone() { try { ByteArrayOutputStream baos = new ByteArrayOutputStream().