Documente Academic
Documente Profesional
Documente Cultură
Serializarea obiectelor
Serializarea este o metod\ prin care se pot salva, ntr-o manier\ unitar\, datele mpreun\ cu signatura unui obiect. Folosind aceast\ opera]ie se poate salva ntr-un fi[ier, ca [ir de octe]i, o instan]\ a unei clase, n orice moment al execu]iei. De asemenea, obiectul poate fi restaurat din fi[ierul n care a fost salvat n urma unei opera]ii de serializare. Salvarea datelor napsulate ntr-un obiect se poate face [i prin salvarea pe rnd a datelor, folosind clasa DataOutputStream, pentru ca apoi s\ fie restaurate prin metode ale clasei DataInputStream, dar o asemenea abordare nu este n general suficient\, deoarece pot ap\rea probleme cum ar fi : datele obiectului pot fi instan]e ale altor obiecte n unele cazuri, este necesar\ [i salvarea tipului datei unele cmpuri fac referin]\ la acela[i obiect A[adar, prin serializare sunt surprinse att 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 ntr-un fi[ier, n acela[i fi[ier putnd 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 ntr-un fi[ier se realizeaz\ astfel :
MyObject o = new MyObject(); FileOutputStream fout = new FileOutputStream(fisier); ObjectOutputStream sout = new ObjectOutputStream(fout); sout.writeObject(o);
Serializarea obiectelor
Restaurarea unui obiect salvat ntr-un fi[ier se face ntr-o manier\ asem\n\toare:
FileInputStream fin = new FileInputStream(fisier); ObjectInputStream sin = new ObjectInputStream(fin); o = (MyObject) sin.readObject();
Pe lng\ metodele de scriere/citire a obiectelor cele dou\ clase pun la dispozi]ie [i metode pentru scrierea tipurilor de date primare, astfel nct 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
att pentru scrierea/citirea datelor primitive, ct [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 rndul lor metodele implicte de transfer defaultWriteObject [i defaultReadObject (avnd acelea[i signaturi ca mai sus) Clasa ObjectOutputStream Constructor
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
Serializarea obiectelor void write( byte[] b, int off, int len ) throws java.io.IOException void void void void void void void void void void write( int data ) throws java.io.IOException writeBoolean( boolean data ) throws java.io.IOException writeByte( int data ) throws java.io.IOException writeBytes( java.lang.String data ) throws java.io.IOException writeChar( int data ) throws java.io.IOException writeChars( java.lang.String data ) throws java.io.IOException writeDouble( double data ) throws java.io.IOException writeFloat( float data ) throws java.io.IOException writeInt( int data ) throws java.io.IOException 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
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
Serializarea obiectelor 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 cmp s\ nu fie salvat n urma serializ\rii, acesta trebuie declarat cu modificatorul transient. Aceste cmpuri 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;
Serializarea obiectelor public MyObject(int x, int y) { this.x = x; this.y = y; } public String toString() { return new String("x=" + x + ", y="+y); } }
A fost salvat obiectul x=10, y=20 Restauram... A fost restaurat obiectul x=10, y=0
Obs. Atunci cnd o clas\ serializabil\ deriv\ dintr-o alt\ clas\, salvarea cmpurilor clasei p\rinte se va face doar dac\ [i aceasta este serializabil\. In caz contrar, subclasa trebuie s\ salveze explicit [i cmpurile mo[tenite. Ex1:
class Parinte implements Serializable { int x; ... } class Fiu extends Parinte implements Serializable { int y; ... }
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 dect s\ declare obiectul o2 ca fiind o referin]\ la obiectul o1. Orice
Serializarea obiectelor
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();
o1 date referin]\ o2 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 dect atunci cnd clasa clonat\ nu are cmpuri referin]\ c\tre alte obiecte, obiectele referite nemaifiind copiate la rndul lor. O metod\ clone() care s\ realizeze o copie efectiv\ a unui obiect, mpreun\ cu copierea tuturor obiectelor referite de cmpurile 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; } }