Documente Academic
Documente Profesional
Documente Cultură
Serializarea obiectelor
2. Un prim exemplu
Exemplul 4. Directorul surs conine clasa Angajat:
import java.io.*; public class Angajat implements Serializable { String nume; int varsta; int salariu; static String firma; public Angajat(String n, int v, int s) { nume=n; varsta=v; salariu=s; } public void print() { System.out.println("Firma:\t\t" + firma + "\n" + "Nume:\t\t" + nume + "\n" + "Varsta:\t\t" + varsta + "\n" + "Salariul:\t" + salariu + "\n"); }
i clasa Serial:
2
import java.io.*; public class Serial { public static void main(String[] sir) throws Exception { Angajat.firma = "SRL Serial"; Angajat Unu = new Angajat("Vasile", 25, 1485); Angajat Doi = new Angajat("Ion", 24, 420); FileOutputStream fos = new FileOutputStream("Serial"); ObjectOutputStream oos = new ObjectOutputStream(fos); // oos.writeUTF(Angajat.firma); oos.writeObject(Unu); oos.writeObject(Doi); oos.close(); fos.close(); } }
Facem deocamdat abstracie de coninutul comentariilor de sfrit de linie. Clasa ObjectOutputStream extinde clasa abstract OutputStream. Prin invocarea metodei writeObject se realizeaz serializarea (ntr-un mod standard) a obiectelor create i scrierea rezultatului serializrii n fluxul de ieire. Clasa Angajat implementeaz interfaa Serializable. Prin abuz de limbaj vom numi clas serializabil o clas ce implementeaz aceast interfa. S reinem c numai instanele unei clase serializabile pot fi serializate. Mai observm c un flux de serializare poate conine mai multe obiecte. Presupunem n continuare c n directorul destinaie apar (de exemplu au fost copiate) fiierele Angajat i Serial, precum clasa Serial1:
import java.io.*; public class Serial1 { public static void main(String args[]) throws Exception { FileInputStream fis = new FileInputStream("Serial"); ObjectInputStream ois = new ObjectInputStream(fis); // Angajat.firma = ois.readUTF(); Angajat Unu = (Angajat) ois.readObject(); Angajat Doi = (Angajat) ois.readObject(); Unu.print(); Doi.print(); ois.close(); fis.close(); } }
Clasa ObjectInputStream extinde clasa abstract InputStream. Prin invocarea metodei readObject se realizeaz deserializarea (ntr-un mod standard) a obiectelor din fluxul de intrare. Metoda readObject ntoarce un obiect de tipul Object, ceea ce face necesar conversia explicit la tipul Angajat. S observm c la ieire, n dreptul numelui firmei apare null. Aceasta se datoreaz faptului c n mecanismul de serializare nu sunt incluse i cmpurile statice. Explicaia const n aceea c serializarea se refer la obiecte, iar cmpurile statice sunt variabile de clas. Dac vom transforma comentariile de sfrit de linie din clasele de mai sus n instruciuni efective, atunci i cmpul static firma va fi inclus n procesul de serializare. Drept urmare, la ieire va aprea i numele firmei. Deci pentru a fi i ele transmise, cmpurile statice trebuie incluse explicit n fluxul de ieire.
3. Ce se transmite la serializare?
Rspundem parial, menionnd c nu sunt transmise cmpurile statice i nici corpurile metodelor: este transmis numai signatura lor. Exemplul 5. Serializm un obiect al urmtoarei clase:
import java.io.*; public class C implements Serializable { int x,y; C(int a, int b) { x = a; y = b; } } void print() { System.out.println("Suma =\t" + (x+y)); }
Dac la deserializare n directorul destinaie n metoda print a clasei UnuC nlocuim (x+y) prin (x*y), iar obiectul de tipul UnuC obinut prin deserializare invoc aceast metod, la ieire va aprea produsul (i nu suma) celor dou cmpuri. ntrebare: Cte obiecte sunt serializate la serializarea unui obiect? Intervine noiunea de graf asociat unui obiect. Graful asociat unui obiect const din obiectul respectiv, dar i din obiectele referite direct sau indirect de el. La serializarea unui obiect este serializat ntregul graf asociat obiectului respectiv. Aceast facilitate este foarte util i poate fi folosit de exemplu pentru: - transmiterea unui arbore; este suficient s serializm rdcina i vor fi serializate toate vrfurile arborelui, mpreun cu structura de arbore; - transmiterea unei liste circulare: este suficient s serializm primul element al listei i vor fi serializate toate elementele listei, mpreun cu structura de list circular; n particular, serializarea "nu se ncurc" dac un obiect din graful asociat se autorefer. Exemplul 6. Serializarea unei liste circulare nevide. Directorul surs conine clasa element:
import java.io.*; import java.util.*; class element implements Serializable { int info; element leg; static element p,u; element() { } element(int i) { info = i; } void creare() { element x; Scanner sc = new Scanner(System.in); int i = sc.nextInt(); p = new element(i); u = p; while ( sc.hasNextInt() ) { x = new element( sc.nextInt() ); u.leg = x; u = x; } u.leg = p; }
4
String parcurg(element x) { if (x.leg == p) return x.info + ""; else return x.info + "\t" + parcurg(x.leg); } }
Metoda principal a clasei Lista1 construiete o list nlnuit circular format din ntregii citii de la intrare pn la ntlnirea unei entiti care nu este un ntreg. Capul listei apare n cmpul static p al clasei elem. La serializarea lui p sunt de fapt serializate toate elemetele (obiectele) din list, adic ntreg graful asociat acestui obiect, precum i structura de list. ntr-adevr, dac n directorul destinaie includem clasa element i urmtoarea clas Lista2:
import java.io.*; public class Lista2 { public static void main(String[] sir) throws Exception { FileInputStream fis = new FileInputStream("lista"); ObjectInputStream ois = new ObjectInputStream(fis); element.p = (element) ois.readObject(); element Ob = new element(); System.out.println( Ob.parcurg(element.p) ); ois.close(); fis.close();
} }