Szerializalas jegyzet
A VIK Wikiből
Jelen jegyzet, leírás, segédlet nevezzük bárhogy megpróbálja az Objektumorientált Szoftvertervezés és Szoftvertechnológia tárgyakban előszeretettel kérdezett Java szerializálás témaköréből egy áttekinthető, konyhanyelven készült leírást szolgáltatni, sok-sok példával.
Alapok, amiket jó ha tudunk
- Alapvetően minden nem statikus és nem tranzies attribútuma egy osztálynak szerializálódik, amely megvalósítja a Serializable interfészt.
- Két nagyon fontos metódus játszik fő szerepet a szerializálásban:
- private void writeObject (ObjectOutputStream out) throws IOException
- A metódus gyakorlatilag teljes kontrollt biztosít a szerializálandó objektum sorosítása felett. A legtöbb esetben egy out.defaultWriteObject() metódushívással kezdődik ezen metódusok implementálása, majd ezt követően lehetőségünk van egyéb adatok sorosítására az erre alkalmas metódusok meghívásával mint pl. az out.writeDouble.
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
- A writeObject metódus ellentéte, a korábban szerializált obejktumokat ezzel a metódussal tudjuk beolvasni. Felüldefiniálásakor az implementáció itt is - a writeObject-hez hasonlóan - az automatikusan szerializált adatok automatikus visszaolvasásával kezdődik, ami a in.defaultReadObject() meghívásával történik. Ezek után beolvassuk azon extra adatokat amelyeket korábban a writeObject() metódussal szerializáltunk. Fontos, hogy a típusegyezésre nekünk kell figyelnünk, így beolvasáskor helyesen kell kasztolnunk, illetve a primitív típusok esetén a megfelelő beolvasó metódust kell meghívnunk.
- private void writeObject (ObjectOutputStream out) throws IOException
- Egy, két nyalánkság:
- private Object writeReplace() throws ObjectStreamException
- A metódus segítségével létrehozható egy "helyettesítő" objektum. A szerializálás során ez az újonnan létrehozott objektum fog szerializálódni az eredeti helyett.
- Az ObjectOuputStream ellenőrzi, hogy a sorosítani kívánt osztály definiál-e writeReplace() metódust, és ha igen meghívja azt először majd az így visszaadott objektumot fogja végül sorosítani.
- private Object readResolve() throws ObjectStreamException
- A writeReplace() ellentéte. Ha a metódus definiált az osztályban, akkor az objektum beolvasása előtt, ennek a metódusnak az eredményét "olvassa be" a korábban szerializált helyett.
- private Object writeReplace() throws ObjectStreamException
Korábbi vizsgapéldák
OOT - 2015. június 2.
public class A implements Serializable { private int x = 1; public transient int y = 2; private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("y", Integer.TYPE) }; public A() { x = 3; y = 4; } public Object writeReplace() throws ObjectStreamException { A a = new A(); a.x = 5; a.y = 6; return a; } }
Megoldás, magyarázat
A Java, csodálatos módon megengedi azt, hogy egy transient-nek - tehát alapvetően nem szerializálódó - jelölt attribútumot mégis tudjunk sorosítani. Ezt a csodálatos lehetőséget úgy valósítja meg, hogy
OOT - 2015. június 9.
public class A implements Serializable { private transient int x = 8; public int y = 4; public A () { x = 0; y = 4; } private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("x", Integer.TYPE) }; private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ in.defaultReadObject(); x = y + 4; } }