Bevezetés a Java Serialization-be

1. Bemutatkozás

A szerializálás az objektum állapotának átalakítása bájtfolyammá; a deserializáció éppen ellenkezőleg jár el. Másképp fogalmazva, a szerializálás egy Java objektum konvertálása bájtok statikus folyamává (szekvenciájává), amelyet ezután elmenthet egy adatbázisba vagy átvihet egy hálózaton keresztül.

2. Serializáció és deserializáció

A sorosítási folyamat példányfüggetlen, vagyis az objektumok sorosíthatók az egyik platformon, és deserializálhatók egy másik platformon. A sorosításra alkalmas osztályoknak speciális marker interfészt kell megvalósítaniukSorosítható.

Mindkét ObjectInputStream és ObjectOutputStream magas szintű osztályok, amelyek kiterjednek java.io.InputStream és java.io.OutputStream illetőleg. ObjectOutputStream írhat primitív típusú objektumokat és grafikonokat egy OutputStream bájtfolyamként. Ezek a folyamok később felhasználhatók ObjectInputStream.

A legfontosabb módszer ObjectOutputStream az:

public final void writeObject (Object o) dobja az IOException-t;

Ami egy sorozható objektumot vesz fel és bájtsorrenddé (folyammá) alakítja. Hasonlóképpen, a legfontosabb módszer a ObjectInputStream az:

public final Az objektum readObject () dobja az IOException-t, a ClassNotFoundException-t;

Ami el tudja olvasni a bájtfolyamot, és visszaalakíthatja Java objektummá. Ez aztán visszadobható az eredeti objektumra.

Illusztráljuk a sorosítást a-val Személy osztály. Vegye figyelembe, hogy a statikus mezők egy osztályhoz tartoznak (szemben egy objektummal), és nem sorosítottak. Vegye figyelembe azt is, hogy használhatjuk a kulcsszót átmeneti figyelmen kívül hagyni az osztálymezőket a sorozatosítás során:

public class Személy végrehajtja a Serializable {private static final long serialVersionUID = 1L; statikus karakterlánc ország = "OLASZORSZÁG"; privát int kor; privát karakterlánc neve; átmeneti int magasság; // szerelők és beállítók}

Az alábbi teszt példát mutat egy típusú objektum mentésére Személy egy helyi fájlba, majd olvassa vissza ezt az értéket:

@Test public void whenSerializingAndDeserializing_ThenObjectIsTheSame () () dobja az IOException, ClassNotFoundException {Person person = new Person (); person.setAge (20); person.setName ("Joe"); FileOutputStream fileOutputStream = új FileOutputStream ("yourfile.txt"); ObjectOutputStream objectOutputStream = új ObjectOutputStream (fileOutputStream); objectOutputStream.writeObject (személy); objectOutputStream.flush (); objectOutputStream.close (); FileInputStream fileInputStream = új FileInputStream ("sajátfájl.txt"); ObjectInputStream objectInputStream = új ObjectInputStream (fileInputStream); Személy p2 = (Személy) objectInputStream.readObject (); objectInputStream.close (); assertTrue (p2.getAge () == p.getAge ()); assertTrue (p2.getName (). egyenlő (p.getName ())); }

Használtuk ObjectOutputStream az objektum állapotának fájlba mentésével a FileOutputStream. A fájl „Yourfile.txt” létrejön a projekt könyvtárban. Ezt a fájlt ezután a FileInputStream.ObjectInputStream felveszi ezt a folyamot és átalakítja egy új objektummá p2.

Végül teszteljük a betöltött objektum állapotát, és ez megegyezik az eredeti objektum állapotával.

Figyelje meg, hogy a betöltött objektumot kifejezetten a Személy típus.

3. Java sorosítási figyelmeztetések

Vannak olyan figyelmeztetések, amelyek a Java sorosítására vonatkoznak.

3.1. Öröklés és összetétel

Amikor egy osztály végrehajtja a java.io.Serializálható interfész, az összes alosztálya szintén sorosítható. Ellenkezőleg, ha egy objektum hivatkozik egy másik objektumra, akkor ezeknek az objektumoknak végre kell hajtaniuk a Sorosítható interfész külön, vagy pedig a NotSerializableException dobni fogják:

public class Személy végrehajtja a Serializálható {private int age; privát karakterlánc neve; privát cím ország; // szintén serializálhatónak kell lennie} 

Ha egy sorozható objektum egyik mezője objektumok tömbjéből áll, akkor ezeknek az objektumoknak is sorosíthatóknak kell lenniük, különben NotSerializableException dobni fogják.

3.2. Soros verzió UID

A JVM társít egy verziót (hosszú) számot minden sorozható osztályhoz. Arra használják, hogy ellenőrizzék, hogy a mentett és betöltött objektumok ugyanazokkal az attribútumokkal rendelkeznek-e, és ezért kompatibilisek-e a szerializáláskor.

Ezt a számot a legtöbb IDE automatikusan előállíthatja, és az osztály nevén, annak attribútumain és a hozzájuk tartozó hozzáférés-módosítókon alapul. Bármely változás más számot eredményez, és okozhat InvalidClassException.

Ha egy sorozatozható osztály nem nyilatkozik a serialVersionUID, a JVM automatikusan generál egyet futás közben. Azonban nagyon ajánlott, hogy minden osztály nyilatkozjon serialVersionUID mivel a létrehozott fordító függ a fordítótól, és ez váratlant eredményezhet InvalidClassExceptions.

3.3. Egyéni sorosítás Java-ban

A Java meghatározza az objektumok sorosítási alapértelmezett módját. A Java osztályok felülírhatják ezt az alapértelmezett viselkedést. Az egyedi sorosítás különösen hasznos lehet, ha olyan objektumot próbál sorosítani, amely rendelkezik néhány nem szeriaalizálható attribútummal. Ezt úgy tehetjük meg, hogy két módszert biztosítunk az osztályon belül, amelyet sorosítani szeretnénk:

private void writeObject (ObjectOutputStream out) dobja az IOException-t;

és

private void readObject (ObjectInputStream in) dobja az IOException-t, a ClassNotFoundException-t;

Ezekkel a módszerekkel sorosíthatjuk ezeket a nem sorozatozható attribútumokat más, sorosítható formákba:

public class Munkavállaló Serializálható {private static final long serialVersionUID = 1L; privát tranziens Cím; magánszemély személy; // seters and getters private void writeObject (ObjectOutputStream oos) dobja az IOException {oos.defaultWriteObject (); oos.writeObject (address.getHouseNumber ()); } private void readObject (ObjectInputStream ois) dobja a ClassNotFoundException, IOException {ois.defaultReadObject (); Egész házszám = (Egész szám) ois.readObject (); Cím a = új Cím (); a.setHouseNumber (házszám); this.setAddress (a); }}
public class Cím {private int houseNumber; // beállítók és szerelők}

A következő egység teszteli ezt az egyéni sorosítást:

@Test public void whenCustomSerializingAndDeserializing_ThenObjectIsTheSame () dobja az IOException, ClassNotFoundException {Person p = new Person (); p.setAge (20); p.setName ("Joe"); Cím a = új Cím (); a.setHouseNumber (1); Alkalmazott e = új alkalmazott (); e.setPerson (p); e.setAddress (a); FileOutputStream fileOutputStream = új FileOutputStream ("yourfile2.txt"); ObjectOutputStream objectOutputStream = új ObjectOutputStream (fileOutputStream); objectOutputStream.writeObject (e); objectOutputStream.flush (); objectOutputStream.close (); FileInputStream fileInputStream = új FileInputStream ("yourfile2.txt"); ObjectInputStream objectInputStream = új ObjectInputStream (fileInputStream); Employee e2 = (Employee) objectInputStream.readObject (); objectInputStream.close (); assertTrue (e2.getPerson (). getAge () == e.getPerson (). getAge ()); assertTrue (e2.getAddress (). getHouseNumber () == e.getAddress (). getHouseNumber ()); }

Ebben a kódban azt látjuk, hogyan menthetünk néhány nem sorozatozható attribútumot sorosítással Cím egyedi sorosítással. Ne feledje, hogy a szérializálhatatlan attribútumokat meg kell jelölnünk átmeneti hogy elkerülje a NotSerializableException.

4. Következtetés

Ebben a gyors oktatóanyagban áttekintettük a Java sorosítását, megbeszéltük a szem előtt tartandó fontos dolgokat, és megmutattuk, hogyan kell elvégezni az egyedi sorosítást.

Mint mindig, az oktatóanyagban használt forráskód is elérhető a GitHubon.