Serializarea obiectelor Serializarea este o metod\ prin care se pot salva, intr-o manier\ unitar\, datele impreun\ cu signatura unui obiect. Folosind aceast\ opera]ie se poate salva intr-un fi[ier, ca [ir de octe]i, o instan]\ a unei clase, in orice moment al execu]iei. De asemenea, obiectul poate fi restaurat din fi[ierul in care a fost salvat in urma unei opera]ii de serializare. Salvarea datelor inapsulate intr-un obiect se poate face [i prin salvarea pe rand a datelor, folosind clasa DataOutputStream, pentru ca apoi s\ fie restaurate prin metode ale clasei DataInputStream, dar o asemenea abordare nu este in general suficient\, deoarece pot ap\rea probleme cum ar fi : datele obiectului pot fi instan]e ale altor obiecte in unele cazuri, este necesar\ [i salvarea tipului datei unele campuri fac referin]\ la acela[i obiect 26462vkt97uhy2m A[adar, prin serializare sunt surprinse atat datele, signatura clasei (numele metodelor [i defini]ia lor - nu [i implementarea) precum [i starea obiectului. Pentru a putea fi serializat un obiect trebuie s\ fie instan]\ a unei clase care implementeaz\ una din interfe]ele : - java.io.Serializable sau - java.io.Externalizable (care extinde clasa Serializable) Interfa]a Serialize nu are nici o metod\, ea d\ doar posibilitatea de a specifica faptul c\ se dore[te ca o anumit\ clas\ s\ poat\ fi serializat\. Declara]ia unei astfel de clase ar fi : class ClasaSerializabila implements Serializable {...} In urma serializ\rii obiectele sunt pot fi salvatr intr-un fi[ier, in acela[i fi[ier putand fi salvate [i mai multe obiecte. Opera]iile de intrare ie[ire la nivelul obicetelor se realizeaz\ prin intermediul unor fluxuri de obiecte, implementate de clasele ObjectInputStream [i ObjectOutputStream. Salvarea unui obiect intr-un fi[ier se realizeaz\ astfel : kh462v6297uhhy MyObject o = new MyObject(); FileOutputStream fout = new FileOutputStream(“fisier”); ObjectOutputStream sout = new ObjectOutputStream(fout); sout.writeObject(o); Restaurarea unui obiect salvat intr-un fi[ier se face intr-o manier\ asem\n\toare: FileInputStream fin = new FileInputStream(“fisier”); ObjectInputStream sin = new ObjectInputStream(fin); o = (MyObject) sin.readObject(); Pe lang\ metodele de scriere/citire a obiectelor cele dou\ clase pun la dispozi]ie [i metode pentru scrierea tipurilor de date primare, astfel incat apeluri ca cele de mai jos sunt permise : FileOutputStream ostream = new FileOutputStream("t.tmp"); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeInt(12345); p.writeObject("Today"); p.writeObject(new Date()); p.flush(); ostream.close(); FileInputStream istream = new FileInputStream("t.tmp"); ObjectInputStream p = new ObjectInputStream(istream); int i = p.readInt(); String today = (String)p.readObject(); Date date = (Date)p.readObject(); istream.close(); ObjectInputStream [i ObjectOutputStream implementeaz\ indirect interfe]ele DataInput, respectiv DataOutput, interef]e ce declar\ metode atat pentru scrierea/citirea datelor primitive, cat [i pentru scrierea/citirea obiectelor. Pentru transferul obiectelor sunt folosite metodele: final void writeObject( java.lang.Object obj ) throws java.io.IOException final java.lang.Object readObject( ) throws java.io.OptionalDataException, java.lang.ClassNotFoundException, java.io.IOException Acestea apeleaz\ la randul lor metodele implicte de transfer defaultWriteObject [i defaultReadObject (avand acelea[i signaturi ca mai sus) Clasa ObjectOutputStream Constructor public ObjectOutputStream( java.io.OutputStream out ) throws java.io.IOException Metode void close( ) throws java.io.IOException final void defaultWriteObject( ) throws java.io.IOException void flush( ) throws java.io.IOException void reset( ) throws java.io.IOException void write( byte[] b ) throws java.io.IOException void write( byte[] b, int off, int len ) throws java.io.IOException void write( int data ) throws java.io.IOException void writeBoolean( boolean data ) throws java.io.IOException void writeByte( int data ) throws java.io.IOException void writeBytes( java.lang.String data ) throws java.io.IOException void writeChar( int data ) throws java.io.IOException void writeChars( java.lang.String data ) throws java.io.IOException void writeDouble( double data ) throws java.io.IOException void writeFloat( float data ) throws java.io.IOException void writeInt( int data ) throws java.io.IOException void writeLong( long data ) throws java.io.IOException final void writeObject( java.lang.Object obj ) throws java.io.IOException void writeShort( int data ) throws java.io.IOException void writeUTF( java.lang.String data ) throws java.io.IOException Clasa ObjectInputStream Constructor public ObjectInputStream( java.io.InputStream in ) throws java.io.IOException, java.io.StreamCorruptedException Create an ObjectInputStream that reads from the specified InputStream. The stream header containing the magic number and version number are read from the stream and verified. This method will block until the corresponding ObjectOutputStream has written and flushed the header. Metode int available( ) throws java.io.IOException void close( ) throws java.io.IOException final void defaultReadObject( ) throws java.io.IOException, java.lang.ClassNotFoundException, java.io.NotActiveException int read( byte[] data, int offset, int length ) throws java.io.IOException int read( ) throws java.io.IOException boolean readBoolean( ) throws java.io.IOException byte readByte( ) throws java.io.IOException char readChar( ) throws java.io.IOException double readDouble( ) throws java.io.IOException float readFloat( ) throws java.io.IOException void readFully( byte[] data ) throws java.io.IOException void readFully( byte[] data, int offset, int size ) throws java.io.IOException int readInt( ) throws java.io.IOException java.lang.String readLine( ) throws java.io.IOException long readLong( ) throws java.io.IOException final java.lang.Object readObject( ) throws java.io.OptionalDataException, java.lang.ClassNotFoundException, java.io.IOException short readShort( ) throws java.io.IOException int readUnsignedByte( ) throws java.io.IOException int readUnsignedShort( ) throws java.io.IOException java.lang.String readUTF( ) throws java.io.IOException ynchronized void registerValidation( java.io.ObjectInputValidation obj, int prio ) throws java.io.NotActiveException, java.io.InvalidObjectException int skipBytes( int len ) throws java.io.IOException Cuvintul cheie transient Pentru ca un anumit camp s\ nu fie salvat in urma serializ\rii, acesta trebuie declarat cu modificatorul transient. Aceste campuri vor fi ignorate de metodele writeObject [i readObject. Ex: private transient x; ® ignorat la serializare Exemplu: import java.io.*; public class TestSerial { static MyObject obj; public static void main(String args[]) { obj = new MyObject(10,20); try { FileOutputStream fout = new FileOutputStream("fisier.tmp"); ObjectOutputStream sout = new ObjectOutputStream(fout); sout.writeObject(obj); sout.flush(); sout.close(); fout.close(); System.out.println("A fost salvat obiectul " + obj); } catch (IOException e) {} System.out.println("Restauram..."); try { FileInputStream fin = new FileInputStream("fisier.tmp"); ObjectInputStream sin = new ObjectInputStream(fin); try { obj = (MyObject) sin.readObject(); } catch (ClassNotFoundException e) {} sin.close(); fin.close(); System.out.println("A fost restaurat obiectul " + obj); } catch (IOException e) {} } } class MyObject implements Serializable { int x; private transient int y; public MyObject(int x, int y) { this.x = x; this.y = y; } public String toString() { return new String("x=" + x + ", y="+y); } } Rezultatul acestui program va fi : A fost salvat obiectul x=10, y=20 Restauram... A fost restaurat obiectul x=10, y=0 Obs. Atunci cand o clas\ serializabil\ deriv\ dintr-o alt\ clas\, salvarea campurilor clasei p\rinte se va face doar dac\ [i aceasta este serializabil\. In caz contrar, subclasa trebuie s\ salveze explicit [i campurile mo[tenite. Ex1: class Parinte implements Serializable { int x; ... } class Fiu extends Parinte implements Serializable { int y; ... } La serializare se salveaz\ atat x cat [i y. Ex1: class Parinte { int x; ... } class Fiu extends Parinte implements Serializable { int y; ... } Serializarea nu decurge normal. Folosirea serializ\rii pentru copierea obiectelor Se [tie c\ nu putem copia un obiect prin instruc]iunea de atribuire. O secven]\ de forma: MyObject o1 = new MyObject(10, 20); MyObject o2 = o1; nu face decat s\ declare obiectul o2 ca fiind o referin]\ la obiectul o1. Orice schimbare intr-unul din cele dou\ obiecte se va reflecta [i in cel\lalt. date O posibilitate de a face o copie unui obiect este folosirea metodei clone() a clasei Object. MyObject o1 = new MyObject(10, 20); MyObject o2 = (MyObject) o1.clone(); date date(copie) Conversia la clasa MyObject este necesar\ deoarece metoda clone() returneaz\ un obiect de tip Object. Deficien]a acestei metode este c\ nu func]ioneaz\ corect decat atunci cand clasa clonat\ nu are campuri referin]\ c\tre alte obiecte, obiectele referite nemaifiind copiate la randul lor. O metod\ clone() care s\ realizeze o copie efectiv\ a unui obiect, impreun\ cu copierea tuturor obiectelor referite de campurile acelui obiect poate fi implementat\ prin mecanismul serializ\rii astfel : public Object clone() { try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(this); out.close(); ByteArrayInputStream bin = new ByteArrayInputStream(); ObjectInputStream in = new ObjectInputStream(bin); Object ret = in.readObject(); in.close(); return ret; } catch (Exception e) { System.out.println(e); return null; } }