Aký je koncept serializácie v Jave?



Tento článok pomôže komplexnému prístupu k konceptu serializácie v Jave spolu s príkladmi v reálnom čase pre lepšie pochopenie.

Serializácia v je dôležitý koncept, ktorý sa zaoberá konverziou objektov do bajtového toku na prenos java objektov z jedného Java Virtual Machine do druhého a ich opätovné vytvorenie do pôvodnej podoby. Doklady tohto článku zoradím takto:

Čo je to serializácia v Jave?

Serializácia v jazyku Java je proces premeny kódu Java Objekt do a Bajtový prúd , aby ste preniesli kód objektu z jedného virtuálneho počítača Java do druhého a znovu ho vytvorili pomocou procesu Deserializácia.





Serialization-in-Java-Edureka-Picture-1

Prečo potrebujeme serializáciu v Jave ?

Serializáciu potrebujeme z nasledujúcich dôvodov:



  • Komunikácia : Serializácia zahŕňa postup objektu serializácia a prenos. To umožňuje viacerým počítačovým systémom navrhovať, zdieľať a vykonávať objekty súčasne.

  • Ukladanie do pamäte cache : Čas strávený pri stavbe objektu sa porovnáva viac s časom potrebným na jeho serializáciu. Serializácia minimalizuje časovú náročnosť o ukladanie do pamäte cache obrie predmety.

  • Deep Copy : Klonovanie proces je jednoduchý pomocou Serializácie. Presne replika objektu získaserializáciu objektu na a bajtové pole a potom ju serializovať.



  • Kríž Synchronizácia JVM: Hlavnou výhodou serializácie je to, žefunguje na rôznych JVM, ktoré môžu bežať na iných architektúry alebo Operačné systémy

  • Vytrvalosť: Stav ľubovoľného objektu je možné priamo uložiť použitím serializácie a uložiť do a databázy aby to mohlo byť načítané neskôr.

Ako serializujeme objekt?

TO Objekt Java je serializovateľné ak a len vtedy, ak jej trieda alebo niektorá z jej materských tried implementuje buď java . Ja . Serializovateľné rozhranie alebo jeho podrozhranie, java.io.Externalizable.

V procese serializácie prevádzame stav objektu na bajtový prúd, aby ho bolo možné preniesť z jedného JVM do druhého, a bajtový prúd vrátime späť do pôvodného objektu.

//Rozhranie

balík Serial1 import java.io.Serializable verejná trieda Zamestnanec implementuje Serializable {private static final long serialVersionUID = 1L // Serial Version UID int id Názov reťazca public Employee (int id, String name) {this.id = id this.name = name }}

// Serializovať

balíček Serial1 import java.io. * trieda Persist {public static void main (String args []) {try {Employee emp1 = new Employee (20110, 'John') Employee emp2 = new Employee (22110, 'Jerry') Employee emp3 = new Employee (20120, 'Sam') FileOutputStream fout = new FileOutputStream ('output.txt') ObjectOutputStream out = new ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Serializácia a deserializácia bola úspešne vykonaná')} catch (Výnimka e) {System.out.println (e)}}}

Výkon:

Serializácia a deserializácia bola úspešne vykonaná

Deserializácia : Je to reverzný proces serializácie, keď sa na prijímajúcom konci znova vytvorí stream serializovaného bajtu objektu od odosielateľa.

// Deserializácia

balík Serial1 import java.io. * class Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Employee e1 = (Employee) in.readObject ( ) Zamestnanec e2 = (Zamestnanec) in.readObject () Zamestnanec e3 = (Zamestnanec) in.readObject () System.out.println (e1.id + '' + e1.name) System.out.println (e2.id + '') + e2.name) System.out.println (e3.id + '' + e3.name) in.close ()} catch (Výnimka e) {System.out.println (e)}}}

Výkon:

20110 Ján
22110 Jerry

20120 Sam

Výhody a nevýhody serializácie v Jave

Výhody:

  • Proces serializácie je a zabudovaný funkcia, ktorá na vykonanie serializácie nevyžaduje softvér tretích strán
  • Je dokázané, že postup serializácie je jednoduché a ľahké rozumieť

  • Postup serializácie je univerzálny a vývojári z rôznych prostredí to poznajú

  • Ľahko sa používa a jednoduché na prispôsobenie

    ako urobiť snímku obrazovky v selenovom webdriveri pomocou
  • Serializované dátové toky podpora šifrovania, kompresie, autentifikácie a bezpečné Java výpočty

  • Je ich veľa kritické technológie spoliehajúc sa na serializáciu.

Nevýhody:

  • Objekty, kým sa stane DeSerializácia krehký a nie sú si istí, či budú efektívne deSerializované.

  • Prechodné premenné deklarované počas serializácie vytvárajú pamäťový priestor, ale nie je volaný konštruktor, čo má za následok zlyhanie pri inicializácii prechodných premenných, čo má za následok zmena štandardného toku Java.

  • Proces serializácie je neefektívne z hľadiska využitia pamäte.

  • Serializácia nie je vhodnejšia na použitie v aplikáciách, ktoré to potrebujú súbežný prístup bez požiadavky API tretích strán , pretože Serializácia neponúka žiadny mechanizmus riadenia prechodu na každú SE.

  • Postup serializácie sa nepodarí ponúknuť jemnozrnná kontrola na prístup k objektom.

Praktické príklady serializácie v Jave

Serializácia pomocou dedičnosti

Prípad 1: Ak je nadtrieda serializovateľná, sú predvolene tiež jej podtriedy serializovateľné.

V takom prípade podtrieda je sériovo serializovateľný, ak nadtrieda implementuje Serializovateľné rozhranie

balíček SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable trieda A implementuje Serializable {int i public A (int i) {this.i = i}} trieda B rozširuje A {int j public B (int i, int j) {super (i) this.j = j}} verejná trieda Test {public static void main (String [] args) vyvolá výnimku {B b1 = nový B (200 400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = nový FileOutputStream ('abc.ser') ObjectOutputStream oos = nový ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Objekt bol serializovaný') FileInputStream fis = nový FileInputStream ('abc.ser') ObjectInputStream ois = nový ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Objekt bol deserializovaný') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Výkon:

j = 20
Objekt bol serializovaný
Objekt bol rekonštruovaný
i = 200
j = 400

Prípad 2: Podtrieda môže byť serializovaná, ak implementuje sériové rozhranie, aj keď nadtrieda sériové rozhranie neimplementuje.

V takom prípade, ak nadtrieda nevykonáva Serializovateľné rozhranie , potom objekty podtrieda je možné manuálne serializovať implementáciou Serializovateľného rozhrania do podtriedy.

balíček SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class superclass {int i public superclass (int i) {this.i = i} public superclass () {i = 50 System.out.println ('Konštruktor nadtriedy s názvom')}} podtrieda triedy rozširuje nadtriedu implementuje Serializable {int j verejná podtrieda (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) throws Exception {subclass b1 = new subclass (10, 20) System.out.println ('i =' + b1.i) System.out.println ( 'j =' + b1.j) FileOutputStream fos = nový FileOutputStream ('output.ser') ObjectOutputStream oos = nový ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Objekt bol serializovaný') FileInputStream fis = nový FileInputStream ('output.ser') ObjectInputStream ois = nová podtrieda ObjectInputStream (fis) b2 = (podtrieda) ois.readObject ( ) ois.close () fis.close () System.out.println ('Objekt bol rekonštruovaný') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Objekt bol serializovaný
Konštruktor nadtriedy sa volá
Objekt bol rekonštruovaný
i = 50
j = 20

Prípad 3: Ak je nadtrieda serializovateľná, ale nepotrebujeme serializáciu podtriedy.

V takom prípade je možné zabrániť serializácii podtriedyimplementáciou writeObject () a readObject () metódy v podtriede a je potrebné ju hodiť NotSerializableException z týchto metód.

balíček SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import java.io.NotSerializableException import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable trieda Parent i public Parent (int i) {this.i = i}} dieťa triedy rozširuje Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) hodí IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) throws IOException {throw new NotSerializableException ()}} public class test3 {public static void main (String [] args) throws Exception {child b1 = new child (100, 200) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = nový FileOutputStream ('abc.ser') ObjectOutputStream oos = nový ObjectOutputStream ( fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Objekt bolo serializované ') FileInputStream fis = nový FileInputStream (' abc.ser ') ObjectInputStream ois = nový ObjectInputStream (fis) dieťa b2 = (dieťa) ois.readObject () ois.close () fis.close () System.out. println ('Objekt bol deserializovaný') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Výkon:

i = 100
j = 200
Výnimka vo vlákne „main“ java.io.NotSerializableException
na SerializationInheritance.child.writeObject (test3.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (natívna metóda)

Serializácia pomocou statického člena

Serializácia statického poľa člena je v procese serializácie ignorovaná. Serializácia jesúvisí s posledným stavom objektu. Preto sú iba údaje spojené s konkrétnou inštanciou triedyserializované, ale nie pole statického člena.

balíček stati import java.io. * trieda StaticSerial implementuje Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('V čase serializácie, statický člen má hodnotu: '+ i) skúsiť {FileOutputStream fos = nový FileOutputStream (' F: File.ser ') ObjectOutputStream oos = nový ObjectOutputStream (fos) oos.writeObject (ob) oos.close () i = 99 FileInputStream fis = new FileInputStream ('F: File.ser') ObjectInputStream ois = new ObjectInputStream (fis) ob = (StaticSerial) ois.readObject () ois.close () System.out.println ('After Deserialization, static member has value:' + i)} chytiť (Výnimka e) {System.out.println (e)}}}

Výkon:

V čase serializácie má statický člen hodnotu: 100
Po deserializácii má statický člen hodnotu: 99

Externalizovateľné rozhranie

The Externalizovateľné rozhranie v Jave je podobný Serializácii, ale jediný rozdiel je v tom, že je schopný ponúknuť prispôsobená serializácia kde môžete rozhodnúť o objektoch, ktoré sa majú v prúde zoradiť.

Rozhranie Externalizable je k dispozícii v java.io a poskytuje dve metódy:

  • public void writeExternal (ObjectOutput out) vyvolá IOException
  • public void readExternal (ObjectInput in) vyvolá IOException

Hlavné rozdiely medzi serializáciou a externalizáciou sú tieto:

  • Implementácia : Externalizovateľné rozhranie okrem používateľa znamená výslovne uveďte objekty, ktoré sa majú serializovať. V rozhraní serializácie sú všetky objekty a premenné serializované v priečinku beh programu.

  • Metódy : Externalizovateľné rozhranie sa skladá z dvoch metód, a to:

    • writeExternal ()

    • readExternal ()

Zatiaľ čo Serializable Interface neobsahuje žiadne metódy.

  • Postup: Proces serializácie vo externom rozhraní poskytuje prispôsobenie do procesu serializácie. Serializačné rozhranie však poskytne predvolené proces serializácie.

  • Spätná kompatibilita a ovládanie: Externalizovateľné rozhranie podporuje serializáciu bez ohľadu na kontrola verzie a jediný problém je, že používateľ musí byť pri serializácii Super Class zodpovedný. Na druhej strane Serializačné rozhranie vyžaduje rovnaká verzia JVM na oboch koncoch, ale obsahuje automatickú serializáciu všetkých objektov a tried vrátane nadtriedy.

  • Verejný konštruktér No-Arg: Potreby externalizačného rozhrania Verejný konštruktér No-Arg rekonštruovať serializovaný objekt. Serializačné rozhranie síce nevyžaduje konštruktor No-Arg, ale naopak používa odraz rekonštruovať serializovaný objekt alebo triedu.

    java je vs má a

balíček ext import java.io. * trieda Demo implementuje java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} test triedy {public static void main (String [] args) {Demo object = new Demo (1, 'Welcome to Edureka') String filename = 'file.ser' try {FileOutputStream file = new FileOutputStream (filename) ObjectOutputStream out = new ObjectOutputStream (file) out .writeObject (object) out.close () file.close () System.out.println ('Object has been serialized')} catch (IOException ex) {System.out.println ('IOException is caught')} Demo object1 = nulový pokus {FileInputStream súbor = nový FileInputStream (názov súboru) ObjectInputStream v = nový ObjectInputStream (súbor) objekt1 = (ukážka) in.readObject () in.close () file.close () System.out.println ('Objekt bol deserialized ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException is captured ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException je zachytená')}}}

Prechodné kľúčové slovo

Prechodné kľúčové slovo je a vyhradené kľúčové slovo v Jave. Používa sa ako a premenná upraviť v čase procesu serializácie. Deklarovanie premennej pomocou kľúčového slova Prechod zabráni serializácii premennej.

UID sériovej verzie

Pred začatím procesu serializácie je každá serializovateľná trieda / objekt spojená s a jedinečné identifikačné číslo poskytované JVM hostiteľského počítača. Toto jedinečné ID sa volá UID sériovej verzie . Toto UID sa používa ako identifikácia JVM prijímacieho konca na potvrdenie toho, že sa na prijímajúcom konci rovnaký objekt deerializuje.

Kontroverzie serializácie v Jave

Oracle Architekti majú v úmysle odstrániť serializáciu z Javy, pretože ju považujú za a Hrozná chyba z roku 1997 . Po hektickom výskume vývojári v spoločnosti Oracle zistili niekoľko nedostatkov v koncepcii postupu serializácie, ktoré predstavujú hrozbu pre dáta.

V roku 1997Mark Reinhold uvádza - „ Radi by sme nazývali serializáciu „dar, ktorý sa neustále dáva“, a typom darčeka, ktorý sa stále dáva, sú bezpečnostné chyby. Pravdepodobne tretina všetkých zraniteľností Java zahŕňala serializáciu, čo by mohla byť viac ako polovica. Je to úžasne plodný zdroj zraniteľností, o nestabilitách ani nehovoriac. “.

Existuje šanca, že by serializácia bola odstránená alebo nahradená v nadchádzajúcich aktualizáciách Java a na druhej strane pre začiatočníkov v Java Serialization nemohol byť idealistickou možnosťou v ich projektoch

Osvedčené postupy pri používaní serializácie v Jave

Nasleduje niekoľko osvedčených postupov, ktoré je potrebné dodržať

  • Odporúča sa použitie javadoc @ sériová značka na označenie serializovateľných polí.
  • The .byť prednostne sa používa prípona pre súbory predstavujúce serializované objekty.
  • Neodporúča sa podstúpiť žiadne statické alebo prechodné polia predvolená serializácia.
  • Rozširujúce sa triedy by nemal byť serializovaný, pokiaľ nie je povinné.
  • Vnútorné triedy je potrebné sa vyhnúť zapojeniu do serializácie.

Týmto sme sa dostali na koniec tohto článku. Dúfam, že ste pochopili základy serializácie v Jave, jej typy a funkcie.

Pozrite sa na autor: Edureka, dôveryhodná online vzdelávacia spoločnosť so sieťou viac ako 250 000 spokojných študentov rozmiestnených po celom svete. Výcvikový a certifikačný kurz Edureka Java J2EE a SOA je určený pre študentov a profesionálov, ktorí chcú byť vývojármi Java. Kurz je navrhnutý tak, aby vám dal náskok v programovaní v Jave a naučil vás základné aj pokročilé koncepty Javy spolu s rôznymi Java frameworkmi ako Hibernate & Jar .

Máte na nás otázku? Uveďte to v sekcii komentárov v tomto článku „Serializácia v Jave“ a my sa vám ozveme čo najskôr.