Jaký je koncept serializace v Javě?



Tento článek pomůže s komplexním přístupem k konceptu Serializace v Javě spolu s příklady v reálném čase pro lepší pochopení.

Serializace v je důležitý koncept, který se zabývá převodem objektů do bajtového proudu pro přenos java objektů z jednoho Java Virtual Machine do druhého a jejich opětovné vytvoření do původní podoby. Uspořádám docket pro tento článek, jak je uvedeno níže:

Co je to serializace v Javě?

Serializace v Javě je proces převodu kódu Java Objekt do Byte Stream , přenést kód objektu z jednoho virtuálního počítače Java do jiného a znovu jej vytvořit pomocí procesu Deserializace.





Serialization-in-Java-Edureka-Picture-1

Proč potřebujeme serializaci v Javě ?

Serializaci potřebujeme z následujících důvodů:



  • Sdělení : Serializace zahrnuje postup objektu serializace a přenos. To umožňuje více počítačovým systémům navrhovat, sdílet a spouštět objekty současně.

  • Ukládání do mezipaměti : Čas spotřebovaný při sestavování objektu je více srovnáván s časem potřebným k jeho serializaci. Serializace minimalizuje časovou spotřebu o ukládání do mezipaměti obří objekty.

  • Deep Copy : Klonování proces je jednoduchý pomocí Serializace. Přesně replika objektu získáserializace objektu na a bajtové pole a poté jej serializovat.



  • Přejít Synchronizace JVM: Hlavní výhodou serializace je tofunguje napříč různými JVM, které mohou běžet na různých architektury nebo Operační systémy

  • Vytrvalost: Stav libovolného objektu může být přímo uložen použitím Serializace na něj a uložen v databáze aby to mohlo být načteno později.

Jak můžeme serializovat objekt?

NA Objekt Java je serializovatelný právě když jeho třída nebo některá z jejích nadřazených tříd implementuje buď Jáva . . Serializovatelné rozhraní nebo jeho podrozhraní, java.io.Externalizable.

V procesu serializace převedeme stav objektu na bajtový proud, aby jej bylo možné přenést z jednoho JVM do druhého, a vrátíme bajtový proud zpět do původního objektu.

//Rozhraní

balíček Serial1 import java.io.Serializable veřejná třída Zaměstnanec implementuje Serializable {private static final long serialVersionUID = 1L // Serial Version UID int id Název řetězce public Employee (int id, String name) {this.id = id this.name = name }}

// Serializovat

balíček Serial1 import java.io. * třída 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 ('Serializace a deserializace byla úspěšně provedena')} catch (Výjimka e) {System.out.println (e)}}}

Výstup:

Serializace a deserializace byla úspěšně provedena

Deserializace : Jedná se o reverzní proces serializace, kdy se na přijímacím konci znovu vytvoří datový proud serializovaného bytu od odesílatele.

// Deserializace

balíček Serial1 import java.io. * třída Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Employee e1 = (Employee) in.readObject ( ) Zaměstnanec e2 = (Zaměstnanec) in.readObject () Zaměstnanec e3 = (Zaměstnanec) 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ýjimka e) {System.out.println (e)}}}

Výstup:

20110 John
22110 Jerry

20120 Sam

Výhody a nevýhody serializace v Javě

Výhody:

  • Proces serializace je a vestavěný funkce, která k provedení serializace nevyžaduje software třetích stran
  • Ukázalo se, že postup serializace je jednoduchý a snadný rozumět

  • Postup serializace je univerzální a vývojáři z různých prostředí to znají

  • Je snadno použitelný a jednoduché přizpůsobení

    transformace v informatice s příkladem
  • Serializované datové toky podpora šifrování, komprese, autentizace a zabezpečené výpočetní prostředí Java

  • Je jich mnoho kritické technologie spoléhat se na serializaci.

Nevýhody:

  • Objekty, zatímco se stane DeSerializace křehký a nejsou si jisti, že budou účinně deSerializováni.

  • Přechodné proměnné deklarované během Serializace vytvářejí paměťový prostor, ale konstruktor není volán, což má za následek selhání inicializace přechodných proměnných, což má za následek variace na standardní tok Java.

  • Proces serializace je neefektivní z hlediska využití paměti.

  • Serializace není vhodnější pro použití v aplikacích, které potřebují souběžný přístup bez požadavku API třetích stran , protože Serializace nenabízí žádný mechanismus řízení přechodu na každou SE.

  • Postup serializace se nenabízí jemnozrnná kontrola pro přístup k objektům.

Praktické příklady serializace v Javě

Serializace pomocí dědičnosti

Případ 1: Pokud je Superclass Serializable, pak jsou ve výchozím nastavení také jeho podtřídy serializovatelné.

V tomto případě podtřída je serializovatelný ve výchozím nastavení, pokud nadtřída provádí Serializovatelné rozhraní

balíček SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable třída A implementuje Serializable {int i public A (int i) {this.i = i}} třída B rozšiřuje A {int j public B (int i, int j) {super (i) this.j = j}} veřejná třída Test {public static void main (String [] args) vyvolá výjimku {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 = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Objekt byl serializován') FileInputStream fis = nový FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Objekt byl deserializován') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Výstup:

j = 20
Objekt byl serializován
Objekt byl deserializován
i = 200
j = 400

Případ 2: Podtřídu lze serializovat, pokud implementuje Serializovatelné rozhraní, i když Superclass Serializovatelné rozhraní neimplementuje.

V tomto případě, pokud nadtřída neimplementuje Serializovatelné rozhraní , pak objekty podtřída lze ručně serializovat implementací Serializovatelného rozhraní v podtřídě.

balíček SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable třída nadtřída {int i veřejná nadtřída (int i) {this.i = i} public superclass () {i = 50 System.out.println ('konstruktor nadtřídy s názvem')}} podtřída třídy rozšiřuje nadtřídu implementuje Serializable {int j veřejná podtřída (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 byl serializován') FileInputStream fis = nový FileInputStream ('output.ser') ObjectInputStream ois = nová ObjectInputStream (fis) podtřída b2 = (podtřída) ois.readObject ( ) ois.close () fis.close () System.out.println ('Objekt byl deserializován') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Objekt byl serializován
Volal konstruktor nadtřídy
Objekt byl deserializován
i = 50
j = 20

Případ 3: Pokud je nadtřída serializovatelná, ale nepotřebujeme serializaci podtřídy.

V tomto případě lze zabránit Serializaci podtřídyimplementací writeObject () a readObject () metody v podtřídě a je třeba ji hodit NotSerializableException z těchto metod.

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 třída Parent i public Parent (int i) {this.i = i}} dítě třídy rozšiřuje 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 byl serializován ') FileInputStream fis = nový FileInputStream (' abc.ser ') ObjectInputStream ois = nový ObjectInputStream (fis) dítě b2 = (dítě) ois.readObject () ois.close () fis.close () System.out. println ('Objekt byl deserializován') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Výstup:

i = 100
j = 200
Výjimka ve vlákně 'main' java.io.NotSerializableException
na SerializationInheritance.child.writeObject (test3.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (nativní metoda)

Serializace pomocí statického člena

Serializace statického pole člena je v procesu serializace ignorována. Serializace jesouvisející s posledním stavem objektu. Proto jsou pouze data přidružená ke konkrétní instanci třídyserializováno, ale ne statické pole člena.

balíček stati import java.io. * třída StaticSerial implementuje Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('V době Serializace, statický člen má hodnotu: '+ i) zkuste {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)} catch (Výjimka e) {System.out.println (e)}}}

Výstup:

V době serializace má statický člen hodnotu: 100
Po deserializaci má statický člen hodnotu: 99

Externalizovatelné rozhraní

The Externalizovatelné rozhraní v Javě je podobný Serializaci, ale jediný rozdíl je v tom, že je schopen nabídnout přizpůsobená serializace kde můžete rozhodnout o objektech, které se mají v proudu streamovat.

Rozhraní Externalizable je k dispozici v java.io a poskytuje dvě metody:

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

Klíčové rozdíly mezi serializací a externalizací jsou následující:

  • Implementace : Externalizovatelné rozhraní s výjimkou uživatele výslovně uveďte objekty, které mají být serializovány. Zatímco v Serializačním rozhraní jsou všechny objekty a proměnné serializovány v run-time.

  • Metody : Externalizovatelné rozhraní se skládá ze dvou metod, a to:

    • writeExternal ()

    • readExternal ()

Zatímco Serializable Interface neobsahuje žádné metody.

  • Proces: Proces serializace ve externím rozhraní poskytuje přizpůsobení do procesu serializace. Serializační rozhraní však poskytne výchozí proces serializace.

  • Zpětná kompatibilita a ovládání: Externalizovatelné rozhraní podporuje serializaci bez ohledu na ovládání verze a jediným problémem je, že uživatel musí být při serializaci Super Class zodpovědný. Na druhou stranu Serializační rozhraní vyžaduje stejná verze JVM na obou koncích, ale zahrnuje automatickou serializaci všech objektů a tříd včetně nadtřídy.

  • Veřejný konstruktér No-Arg: Potřeby rozhraní externalizace Veřejný konstruktér No-Arg rekonstruovat serializovaný objekt. Zatímco Serializační rozhraní nevyžaduje No-Arg konstruktor, místo toho používá odraz rekonstruovat serializovaný objekt nebo třídu.

    součet číslic čísla v Javě

balíček ext import java.io. * třída Demo implementuje java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} třída Test {veřejná statická 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 captured')} Demo object1 = null try {FileInputStream file = new FileInputStream (filename) ObjectInputStream in = new ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Object has been 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 is chycen')}}}

Přechodné klíčové slovo

Přechodné klíčové slovo je a vyhrazené klíčové slovo v Javě. Používá se jako proměnná upravit v době procesu serializace. Deklarace proměnné pomocí přechodného klíčového slova zabrání serializaci proměnné.

UID sériové verze

Před zahájením procesu serializace bude každá serializovatelná třída / objekt přidružena k jedinečné identifikační číslo poskytované JVM hostitelského počítače. Toto jedinečné ID se nazývá UID sériové verze . Toto UID se používá jako identifikace JVM přijímajícího konce k potvrzení, že stejný objekt je na přijímacím konci DeSerializován.

Kontroverze serializace v Javě

Oracle Architekti mají v úmyslu odstranit Serializaci z Javy, protože ji považují za Hrozná chyba z roku 1997 . Po hektickém výzkumu zjistili vývojáři společnosti Oracle několik nedostatků v návrhu postupu serializace, které představují hrozbu pro data.

V roce 1997Mark Reinhold uvádí - „ Rádi bychom nazývali serializaci „dar, který stále dává“, a typem dárku, který pořád dává, jsou chyby zabezpečení. Pravděpodobně třetina všech zranitelností Java zahrnovala serializaci, což by mohla být více než polovina. Je to neuvěřitelně plodný zdroj zranitelností, nemluvě o nestabilitách. “

Existuje šance, že by Serializace byla odstraněna nebo nahrazena v nadcházejících aktualizacích Javy a na druhou stranu, pro začátečníka v Javě, Serializace nemohl být idealistická volba ve svých projektech

Osvědčené postupy při používání serializace v Javě

Následuje několik osvědčených postupů, které je třeba dodržovat

  • Doporučuje se používat javadoc @ sériová značka pro označení Serializovatelných polí.
  • The .být přípona je upřednostňována pro soubory představující serializované objekty.
  • Nedoporučuje se podstoupit žádná statická nebo přechodná pole výchozí serializace.
  • Rozšiřitelné třídy by neměly být serializovány, pokud tomu tak není povinné.
  • Vnitřní třídy je třeba se vyhnout zapojení do Serializace.

Tím jsme se dostali na konec tohoto článku. Doufám, že jste pochopili základy Serializace v Javě, její typy a funkce.

Podívejte se na Edureka, důvěryhodná online vzdělávací společnost se sítí více než 250 000 spokojených studentů po celém světě. Školicí a certifikační kurz Edureka Java J2EE a SOA je určen pro studenty a profesionály, kteří chtějí být vývojářem Java. Kurz je navržen tak, aby vám poskytl náskok v programování v Javě a naučil vás základní i pokročilé koncepty Javy spolu s různými rámci Java, jako je Hibernate & Jaro .

Máte na nás dotaz? Uveďte to v sekci komentářů tohoto článku „Serializace v Javě“ a my se vám ozveme co nejdříve.