Úvod do serializácie Java

1. Úvod

Serializácia je konverzia stavu objektu do bajtového toku; deserializácia robí pravý opak. Inak povedané, serializácia je konverzia objektu Java na statický prúd (postupnosť) bajtov, ktorý je potom možné uložiť do databázy alebo preniesť cez sieť.

2. Serializácia a deserializácia

Proces serializácie je nezávislý na inštanciách, to znamená, že objekty je možné serializovať na jednej platforme a deserializovať na druhej. Triedy, ktoré sú vhodné na serializáciu, musia implementovať špeciálne rozhranie značiekSerializovateľné.

Oboje ObjectInputStream a ObjectOutputStream sú triedy na vysokej úrovni, ktoré sa rozširujú java.io.InputStream a java.io.OutputStream resp. ObjectOutputStream dokáže písať primitívne typy a grafy objektov do formátu OutputStream ako prúd bajtov. Tieto streamy je možné následne čítať pomocou ObjectInputStream.

Najdôležitejšia metóda v ObjectOutputStream je:

public final void writeObject (Object o) hodí IOException;

Ktorý vezme serializovateľný objekt a prevedie ho na sekvenciu (prúd) bajtov. Podobne najdôležitejšia metóda v ObjectInputStream je:

public final Object readObject () hodí IOException, ClassNotFoundException;

Ktorý dokáže prečítať prúd bajtov a previesť ho späť na objekt Java. To potom možno vrhať späť na pôvodný objekt.

Poďme si ilustrovať serializáciu pomocou a Osoba trieda. Poznač si to statické polia patria do triedy (na rozdiel od objektu) a nie sú serializované. Upozorňujeme tiež, že môžeme použiť kľúčové slovo prechodný ignorovať polia triedy počas serializácie:

verejná trieda Osoba implementuje Serializable {private static final long serialVersionUID = 1L; static String country = "TALIANSKO"; súkromný int vek; súkromné ​​meno reťazca; prechodná int výška; // zakladatelia a zakladatelia}

Test uvedený nižšie ukazuje príklad uloženia objektu typu Osoba do lokálneho súboru a potom načítať túto hodnotu späť do:

@ Test public void whenSerializingAndDeserializing_ThenObjectIsTheSame () () vyvolá IOException, ClassNotFoundException {Person person = new Person (); person.setAge (20); person.setName ("Joe"); FileOutputStream fileOutputStream = nový FileOutputStream ("yourfile.txt"); ObjectOutputStream objectOutputStream = nový ObjectOutputStream (fileOutputStream); objectOutputStream.writeObject (osoba); objectOutputStream.flush (); objectOutputStream.close (); FileInputStream fileInputStream = nový FileInputStream ("váš súbor.txt"); ObjectInputStream objectInputStream = nový ObjectInputStream (fileInputStream); Osoba p2 = (Osoba) objectInputStream.readObject (); objectInputStream.close (); assertTrue (p2.getAge () == p.getAge ()); assertTrue (p2.getName (). equals (p.getName ())); }

Použili sme ObjectOutputStream na uloženie stavu tohto objektu do súboru pomocou FileOutputStream. Súbor „Yourfile.txt“ je vytvorený v adresári projektu. Tento súbor sa potom načíta pomocou FileInputStream.ObjectInputStream zdvihne tento prúd a prevedie ho na nový objekt s názvom p2.

Nakoniec otestujeme stav načítaného objektu a ten sa zhoduje so stavom pôvodného objektu.

Všimnite si, že načítaný objekt musí byť explicitne obsadený do a Osoba typu.

3. Upozornenia na serializáciu Java

Existujú určité výhrady, ktoré sa týkajú serializácie v Jave.

3.1. Dedenie a zloženie

Keď trieda implementuje java.io. Serializovateľné rozhranie, všetky jeho podtriedy sú tiež serializovateľné. Naopak, ak má objekt odkaz na iný objekt, musia tieto objekty implementovať Serializovateľné rozhranie samostatne, alebo a NotSerializableException bude vyhodené:

public class Osoba implementuje Serializable {private int age; súkromné ​​meno reťazca; krajina súkromnej adresy; // musí byť tiež serializovateľné} 

Ak jedno z polí v serializovateľnom objekte pozostáva z radu objektov, musia byť tiež všetky tieto objekty serializovateľné, inak NotSerializableException bude vyhodený.

3.2. UID sériovej verzie

JVM spája verziu (dlho) číslo s každou serializovateľnou triedou. Slúži na overenie, či uložené a načítané objekty majú rovnaké atribúty a teda sú kompatibilné pri serializácii.

Toto číslo môže väčšina IDE vygenerovať automaticky a je založené na názve triedy, jej atribútoch a súvisiacich modifikátoroch prístupu. Akékoľvek zmeny vedú k inému číslu a môžu spôsobiť InvalidClassException.

Ak serializovateľná trieda nedeklaruje a serialVersionUID, JVM vygeneruje jeden automaticky za behu. Dôrazne sa však odporúča, aby každá trieda deklarovala svoje serialVersionUID pretože vygenerovaný závisí od kompilátora, a preto môže byť neočakávaný InvalidClassExceptions.

3.3. Vlastná serializácia v prostredí Java

Java určuje predvolený spôsob, akým je možné objekty serializovať. Triedy Java môžu toto predvolené správanie prepísať. Vlastná serializácia môže byť obzvlášť užitočná, keď sa pokúšate serializovať objekt, ktorý má niektoré neserializovateľné atribúty. To sa dá dosiahnuť poskytnutím dvoch metód vo vnútri triedy, ktorú chceme serializovať:

private void writeObject (ObjectOutputStream out) vyvolá IOException;

a

private void readObject (ObjectInputStream in) vyvolá IOException, ClassNotFoundException;

Pomocou týchto metód môžeme tieto neserializovateľné atribúty serializovať do ďalších foriem, ktoré je možné serializovať:

verejná trieda Zamestnanec implementuje Serializable {private static final long serialVersionUID = 1L; súkromná prechodná adresa; súkromná osoba; // nastavovatelia a getre private void writeObject (ObjectOutputStream oos) hodí IOException {oos.defaultWriteObject (); oos.writeObject (address.getHouseNumber ()); } private void readObject (ObjectInputStream ois) hodí ClassNotFoundException, IOException {ois.defaultReadObject (); Celé číslo domu = (celé číslo) ois.readObject (); Adresa a = nová adresa (); a.setHouseNumber (číslo domu); this.setAddress (a); }}
public class Adresa {private int houseNumber; // zakladatelia a prijímači}

Nasledujúci test jednotky testuje túto vlastnú serializáciu:

@ Test public void whenCustomSerializingAndDeserializing_ThenObjectIsTheSame () vyvolá IOException, ClassNotFoundException {Person p = new Person (); p.setAge (20); p.setName ("Joe"); Adresa a = nová adresa (); a.setHouseNumber (1); Zamestnanec e = nový zamestnanec (); e.setPerson (p); e.setAddress (a); FileOutputStream fileOutputStream = nový FileOutputStream ("yourfile2.txt"); ObjectOutputStream objectOutputStream = nový ObjectOutputStream (fileOutputStream); objectOutputStream.writeObject (e); objectOutputStream.flush (); objectOutputStream.close (); FileInputStream fileInputStream = nový FileInputStream ("yourfile2.txt"); ObjectInputStream objectInputStream = nový ObjectInputStream (fileInputStream); Zamestnanec e2 = (zamestnanec) objectInputStream.readObject (); objectInputStream.close (); assertTrue (e2.getPerson (). getAge () == e.getPerson (). getAge ()); assertTrue (e2.getAddress (). getHouseNumber () == e.getAddress (). getHouseNumber ()); }

V tomto kóde vidíme, ako ukladať niektoré neserializovateľné atribúty serializáciou Adresa s vlastnou serializáciou. Upozorňujeme, že neserializovateľné atribúty musíme označiť ako prechodný vyhnúť sa NotSerializableException.

4. Záver

V tomto rýchlom výučbe sme preskúmali serializáciu Java, prediskutovali dôležité veci, na ktoré treba pamätať, a ukázali sme, ako vykonať vlastnú serializáciu.

Ako vždy, zdrojový kód použitý v tomto tutoriále je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found