Wat is het concept van serialisatie in Java?



Dit artikel zal helpen met een uitgebreide benadering van het concept van serialisering in Java, samen met realtime voorbeelden voor een beter begrip.

Serialisatie in is een belangrijk concept dat zich bezighoudt met de conversie van objecten naar een bytestream om de java-objecten van de ene Java Virtual Machine naar de andere te transporteren en ze opnieuw te creëren naar de oorspronkelijke vorm. Ik zal de rol voor dit artikel opstellen zoals hieronder:

Wat is serialisatie in Java?

Serialisatie in Java is het proces van het converteren van de Java-code Voorwerp in een Byte stroom , om de objectcode van de ene virtuele Java-machine naar de andere over te brengen en opnieuw te maken met behulp van het proces van Deserialisatie.





Serialization-in-Java-Edureka-Picture-1

Waarom hebben we serialisatie nodig? in Java ?

We hebben serialisering nodig om de volgende redenen:



  • Communicatie : Serialisatie omvat de procedure van object serialisatie en overdragen. Hierdoor kunnen meerdere computersystemen tegelijkertijd objecten ontwerpen, delen en uitvoeren.

  • Caching : De tijd die nodig is om een ​​object te bouwen is meer in vergelijking met de tijd die nodig is om het te deserialiseren. Serialisatie minimaliseert het tijdverbruik door caching de gigantische objecten.

  • Diepe kopie : Klonen proces is eenvoudig gemaakt door gebruik te maken van Serialisatie. Een exact replica van een object wordt verkregen doorserialiseren van het object naar een byte-array en vervolgens de serialisering ervan ongedaan maken.



  • Kruis JVM-synchronisatie: Het grote voordeel van serialisatie is dat hetwerkt op verschillende JVM's die mogelijk op verschillende architecturen of Besturingssystemen

  • Persistentie: De staat van elk object kan direct worden opgeslagen door er serialisering op toe te passen en opgeslagen in een database zodat het kan zijn later opgehaald.

Hoe serialiseren we een object?

NAAR Java-object is serialiseerbaar als en alleen als zijn klasse of een van de bovenliggende klassen ofwel de Java . ik . Serialiseerbaar interface of zijn subinterface, java.io.Externalizable.

In het serialiseringsproces zetten we de toestand van een object om in een bytestream zodat deze van de ene JVM naar de andere kan worden overgebracht en de bytestream terug kan draaien naar het oorspronkelijke object.

//Koppel

pakket Serial1 import java.io.Serializable public class Werknemer implementeert Serializable {private static final long serialVersionUID = 1L // Seriële versie UID int id Stringnaam public Employee (int id, Stringnaam) {this.id = id this.name = name }}

// Serialiseren

pakket Serial1 import java.io. * class Persist {public static void main (String args []) {try {Employee emp1 = new Employee (20110, 'John') Employee emp2 = new Employee (22110, 'Jerry') Employee emp3 = nieuwe medewerker (20120, 'Sam') FileOutputStream fout = nieuwe FileOutputStream ('output.txt') ObjectOutputStream out = nieuwe ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Serialisatie en deserialisatie is met succes uitgevoerd')} catch (uitzondering e) {System.out.println (e)}}}

Uitgang:

Serialisatie en deserialisatie zijn met succes uitgevoerd

Deserialisatie : Het is het omgekeerde proces van serialisatie waarbij de geserialiseerde bytestroom van een object van de afzender opnieuw wordt aangemaakt aan de ontvangende kant.

// Deserialiseren

pakket Serial1 import java.io. * class Depersist {public static void main (String args []) {probeer {ObjectInputStream in = nieuw ObjectInputStream (nieuwe FileInputStream ('output.txt')) Werknemer e1 = (Werknemer) in.readObject ( ) Werknemer e2 = (Werknemer) in.readObject () Werknemer e3 = (Werknemer) 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 (uitzondering e) {System.out.println (e)}}}

Uitgang:

20110 John
22110 Jerry

20120 Sam

Java diepe kopie versus ondiepe kopie

Voordelen en nadelen van serialisering in Java

Voordelen:

  • Het serialiseringsproces is een ingebouwd functie waarvoor geen software van derden nodig is om serialisering uit te voeren
  • De serialisatieprocedure is bewezen gemakkelijk en gemakkelijk begrijpen

  • Serialisatieprocedure is universeel en ontwikkelaars met verschillende achtergronden zijn er bekend mee

  • Het is gemakkelijk te gebruiken en eenvoudig aan te passen

  • Geserialiseerde datastromen ondersteuning voor codering, compressie, authenticatie en veilig Java-computergebruik

  • Er zijn veel kritische technologieën vertrouwend op serialisatie.

Nadelen:

  • Objecten terwijl DeSerialization wordt bros en ze zijn er niet zeker van of ze effectief gedeserialiseerd worden.

  • De tijdelijke variabelen gedeclareerd terwijl serialisering geheugenruimte creëert, maar de constructor wordt niet aangeroepen, wat resulteert in het mislukken van de initialisatie van tijdelijke variabelen, wat resulteert in een variatie op de Standard Java Flow.

  • Het proces van serialisatie is inefficiënt in termen van geheugengebruik.

  • Serialisatie heeft niet de voorkeur om te worden gebruikt in de toepassingen die dat nodig hebben gelijktijdige toegang zonder de vereiste van API's van derden , aangezien Serialisatie geen transitiecontrolemechanisme biedt voor elke SE.

  • Serialisatieprocedure biedt geen mogelijkheid fijnmazige controle om toegang te krijgen tot objecten.

Praktische voorbeelden van serialisatie in Java

Serialisatie met behulp van overerving

Geval - 1: Als Superklasse serialiseerbaar is, zijn de subklassen standaard ook te serialiseren.

In dit geval is het subklasse is standaard serialiseerbaar als de superklasse implementeert het Serialiseerbare interface

pakket SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable klasse A implementeert Serializable {int i public A (int i) {this.i = i}} klasse B breidt A uit {int j public B (int i, int j) {super (i) this.j = j}} public class Test {public static void main (String [] args) gooit Uitzondering {B b1 = nieuw B (200,400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = nieuw FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Het object is geserialiseerd') FileInputStream fis = nieuwe FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Het object is gedeserialiseerd') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Uitgang:

j = 20
Het object is geserialiseerd
Het object is gedeserialiseerd
ik = 200
j = 400

Geval - 2: Een subklasse kan worden geserialiseerd als deze de serialiseerbare interface implementeert, zelfs als een superklasse de serialiseerbare interface niet implementeert.

In dit geval, als het superklasse implementeert het Serialiseerbare interface , dan, de objecten van de subklasse kan handmatig worden geserialiseerd door de Serializable Interface in de subklasse te implementeren.

pakket SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable klasse superklasse {int i openbare superklasse (int i) {this.i = i} public superclass () {i = 50 System.out.println ('Superclass constructor called')}} class subclass breidt superklasse implementeert Serializable {int j public subclass (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) gooit Uitzondering {subklasse b1 = nieuwe subklasse (10, 20) System.out.println ('i =' + b1.i) System.out.println ( 'j =' + b1.j) FileOutputStream fos = nieuwe FileOutputStream ('output.ser') ObjectOutputStream oos = nieuwe ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Het object is geserialiseerd') FileInputStream fis = nieuwe FileInputStream ('output.ser') ObjectInputStream ois = nieuwe ObjectInputStream (fis) subklasse b2 = (subklasse) ois.readObject ( ) ois.close () fis.close () System.out.println ('Het object is gedeserialiseerd') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Het object is geserialiseerd
Superklasse constructor genaamd
Het object is gedeserialiseerd
ik = 50
j = 20

Geval - 3: Als de superklasse kan worden geserialiseerd, maar we hebben de subklasse niet nodig om te worden geserialiseerd.

In dit geval kan de serialisering van de subklasse worden voorkomendoor het implementeren van de writeObject () en readObject () methoden in de subklasse en het moet gooien NotSerializableException van deze methoden.

pakket 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 classizable i public Parent (int i) {this.i = i}} class child verlengt Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) gooit IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) gooit IOException {throw new NotSerializableException ()}} public class test3 {public static void main (String [] args) gooit uitzondering {child b1 = new child (100, 200) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = nieuwe FileOutputStream ('abc.ser') ObjectOutputStream oos = nieuwe ObjectOutputStream ( fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Object is geserialiseerd ') FileInputStream fis = nieuw FileInputStream (' abc.ser ') ObjectInputStream ois = nieuw ObjectInputStream (fis) kind b2 = (kind) ois.readObject () ois.close () fis.close () System.out. println ('Object is gedeserialiseerd') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Uitgang:

ik = 100
j = 200
Uitzondering in thread 'main' java.io.NotSerializableException
bij SerializationInheritance.child.writeObject (test3.java:48)
bij sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)

Serialisatie met behulp van een statisch lid

Serialisatie van statisch lidveld wordt genegeerd tijdens het serialiseringsproces. Serialisatie isgerelateerd aan de laatste staat van het object. Daarom zijn alleen de gegevens die zijn gekoppeld aan een specifiek exemplaar van een klassegeserialiseerd maar niet het statische lidveld.

pakket stati import java.io. * class StaticSerial implementeert Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('Ten tijde van serialisering, statisch lid heeft waarde: '+ i) probeer {FileOutputStream fos = nieuwe FileOutputStream (' F: File.ser ') ObjectOutputStream oos = nieuwe 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 ('Na deserialisatie heeft statisch lid waarde:' + i)} catch (uitzondering e) {System.out.println (e)}}}

Uitgang:

Op het moment van serialisering heeft statisch lid de waarde: 100
Na deserialisatie heeft het statische lid de waarde: 99

Extern aanpasbare interface

De Extern aanpasbare interface in Java is vergelijkbaar met serialisatie, maar het enige verschil is dat het in staat is om te bieden aangepaste serialisatie waar je kunt beslissen welke objecten in de stroom moeten worden beschadigd.

hoe iterator java te gebruiken

De Externalizable interface is beschikbaar in de java.io en biedt twee methoden:

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

De belangrijkste verschillen tussen serialisatie en externizeable zijn als volgt:

lees en schrijf Excel-bestand in java

  • Implementatie : Externalizable Interface behalve de gebruiker voor uitdrukkelijk vermeld de objecten die moeten worden geserialiseerd. In Serialization Interface worden alle objecten en variabelen geserialiseerd in het looptijd.

  • Methoden : Externalizable interface bestaat uit twee methoden, namelijk:

    • writeExternal ()

    • readExternal ()

Terwijl de serialiseerbare interface geen methoden bevat.

  • Werkwijze: Serialisatieproces in Externalizable Interface biedt maatwerk naar het serialisatieproces. Maar Serialization Interface biedt de standaard serialisatieproces.

  • Achterwaartse compatibiliteit en controle: Externalizable Interface ondersteunt serialisatie ongeacht de versiebeheer en het enige probleem is dat de gebruiker verantwoordelijk moet zijn bij het serialiseren van Super Class. Aan de andere kant vereist Serialization Interface het dezelfde versie van JVM's aan beide uiteinden, maar het bevat automatische serialisering van alle objecten en klassen, inclusief de superklasse.

  • Openbare No-Arg Constructor: Externalisatie-interface behoeften Openbare No-Arg Constructor om het geserialiseerde object te reconstrueren. Hoewel Serialization Interface geen No-Arg Constructor vereist, gebruikt het in plaats daarvan reflectie om het geserialiseerde object of de klasse te reconstrueren.

pakket ext import java.io. * class Demo implementeert java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} class Test {public static void main (String [] args) {Demo-object = nieuwe demo (1, 'Welcome to Edureka') String filename = 'file.ser' probeer {FileOutputStream file = nieuwe FileOutputStream (bestandsnaam) ObjectOutputStream out = nieuwe ObjectOutputStream (bestand) uit .writeObject (object) out.close () file.close () System.out.println ('Object is geserialiseerd')} catch (IOException ex) {System.out.println ('IOException is gevangen')} Demo-object1 = null probeer {FileInputStream-bestand = nieuw FileInputStream (bestandsnaam) ObjectInputStream in = nieuw ObjectInputStream (bestand) object1 = (Demo) in.readObject () in.close () bestand.close () System.out.println ('Object is deserialized ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException is gevangen ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException is gevangen')}}}

Voorbijgaand trefwoord

Voorbijgaand trefwoord is een gereserveerd trefwoord in Java. Het wordt gebruikt als een variabele wijzigen op het moment van het serialisatieproces. Door een variabele te declareren met het Transient-sleutelwoord, wordt voorkomen dat de variabele wordt geserialiseerd.

Seriële versie UID

Voordat het serialiseringsproces begint, wordt elke serialiseerbare klasse / object geassocieerd met een uniek identificatienummer geleverd door de JVM van de gastmachine. Deze unieke ID wordt genoemd Seriële versie UID . Deze UID wordt door de JVM van de ontvangende kant gebruikt als identificatie om te bevestigen dat hetzelfde object aan de ontvangende kant wordt gedeserialiseerd.

Controverses van serialisatie in Java

Oracle's Architecten zijn van plan om serialisatie van Java te verwijderen omdat ze het beschouwen als een Afschuwelijke fout van 1997 . Na hectisch onderzoek ontdekten de ontwikkelaars van Oracle een paar tekortkomingen in het ontwerp van de serialiseringsprocedure die een bedreiging vormen voor de gegevens.

In het jaar 1997Mark Reinhold zegt: ' We noemen serialisatie graag 'het geschenk dat blijft geven', en het soort geschenk dat het blijft geven, zijn beveiligingsproblemen. Waarschijnlijk heeft een derde van alle Java-kwetsbaarheden te maken met serialisatie, dit kan meer dan de helft zijn. Het is een verbazingwekkend vruchtbare bron van kwetsbaarheden, om nog maar te zwijgen van instabiliteit. ”.

Er is een kans dat serialisatie wordt verwijderd of vervangen in de komende updates van Java en aan de andere kant, voor een beginner in Java, serialisatie kon niet wees een idealistische optie in hun projecten

Best practices tijdens het gebruik van serialisatie in Java

Hieronder volgen enkele praktische tips die moeten worden gevolgd

  • Het is aanbevolen gebruik javadoc @ seriële tag voor het aangeven van serialiseerbare velden.
  • De .zijn extensie wordt bij voorkeur gebruikt voor bestanden die geserialiseerde objecten vertegenwoordigen.
  • Het wordt niet aanbevolen om statische of tijdelijke velden te ondergaan standaard serialisering.
  • Uitbreidbare lessen mag niet worden geserialiseerd, tenzij het is verplicht.
  • Innerlijke klassen moet worden vermeden om betrokken te zijn bij serialisering.

Hiermee zijn we aan het einde van dit artikel gekomen. Ik hoop dat je de basisprincipes van serialisatie in Java, de typen en functionaliteiten ervan hebt begrepen.

Bekijk de door Edureka, een vertrouwd online leerbedrijf met een netwerk van meer dan 250.000 tevreden leerlingen verspreid over de hele wereld. De training- en certificeringcursus Java J2EE en SOA van Edureka is bedoeld voor studenten en professionals die Java-ontwikkelaar willen worden. De cursus is ontworpen om u een voorsprong te geven in het programmeren van Java en u te trainen in zowel kern- als geavanceerde Java-concepten samen met verschillende Java-frameworks zoals Hibernate De lente .

Heeft u een vraag voor ons? Vermeld het in het commentaargedeelte van dit 'Serialisering in Java' -artikel en we nemen zo snel mogelijk contact met u op.