Gids voor de externaliseerbare interface in Java

1. Inleiding

In deze tutorial we zullen snel naar Java's kijken java.io.Externalizable koppel. Het belangrijkste doel van deze interface is om aangepaste serialisatie en deserialisatie te vergemakkelijken.

Voordat we verder gaan, moet u het artikel over serialisatie in Java lezen. Het volgende hoofdstuk gaat over het serialiseren van een Java-object met deze interface.

Daarna gaan we de belangrijkste verschillen met de java.io.Serializable koppel.

2. Het Uitwendig te maken Koppel

Uitwendig te maken strekt zich uit van de java.io.Serializable marker interface. Elke klasse die implementeert Uitwendig te maken interface moet de writeExternal (), readExternal () methoden. Op die manier kunnen we het standaard serialisatiegedrag van de JVM wijzigen.

2.1. Serialisatie

Laten we dit eenvoudige voorbeeld eens bekijken:

public class Country implementeert Externalizable {private static final long serialVersionUID = 1L; private String naam; privé int-code; // getters, setters @Override public void writeExternal (ObjectOutput out) gooit IOException {out.writeUTF (naam); out.writeInt (code); } @Override public void readExternal (ObjectInput in) gooit IOException, ClassNotFoundException {this.name = in.readUTF (); this.code = in.readInt (); }}

Hier hebben we een klasse gedefinieerd Land dat implementeert de Uitwendig te maken interface en implementeert de twee hierboven genoemde methoden.

In de writeExternal () methode, voegen we de eigenschappen van het object toe aan de ObjectOutput stroom. Dit heeft standaardmethoden zoals writeUTF () voor Draad en writeInt () voor de int-waarden.

De volgende, voor het deserialiseren van het object lezen we uit de ObjectInput stroom de ... gebruiken readUTF (), readInt () methoden om de eigenschappen in dezelfde exacte volgorde te lezen waarin ze zijn geschreven.

Het is een goede gewoonte om het serialVersionUID handmatig. Als dit niet het geval is, zal de JVM er automatisch een toevoegen.

Het automatisch gegenereerde nummer is afhankelijk van de compiler. Dit betekent dat het een onwaarschijnlijke oorzaak kan zijn InvalidClassException.

Laten we het gedrag testen dat we hierboven hebben geïmplementeerd:

@ Test openbare leegte whenSerializing_thenUseExternalizable () gooit IOException, ClassNotFoundException {Country c = new Country (); c.setCode (374); c.setName ("Armenië"); FileOutputStream fileOutputStream = nieuwe FileOutputStream (OUTPUT_FILE); ObjectOutputStream objectOutputStream = nieuwe ObjectOutputStream (fileOutputStream); c.writeExternal (objectOutputStream); objectOutputStream.flush (); objectOutputStream.close (); fileOutputStream.close (); FileInputStream fileInputStream = nieuwe FileInputStream (OUTPUT_FILE); ObjectInputStream objectInputStream = nieuwe ObjectInputStream (fileInputStream); Land c2 = nieuw land (); c2.readExternal (objectInputStream); objectInputStream.close (); fileInputStream.close (); assertTrue (c2.getCode () == c.getCode ()); assertTrue (c2.getName (). is gelijk aan (c.getName ())); }

In dit voorbeeld maken we eerst een Land object en het schrijven naar een bestand. Vervolgens deserialiseren we het object uit het bestand en controleren of de waarden correct zijn.

De output van de gedrukte c2 voorwerp:

Land {naam = 'Armenië', code = 374}

Dit toont aan dat we het object met succes hebben gedeserialiseerd.

2.2. Erfenis

Wanneer een klasse erft van de Serialiseerbaar interface, verzamelt de JVM automatisch ook alle velden van subklassen en maakt ze serialiseerbaar.

Houd er rekening mee dat we dit kunnen toepassen op Uitwendig te maken ook. We hoeven alleen de lees- / schrijfmethoden te implementeren voor elke subklasse van de overervingshiërarchie.

Laten we eens kijken naar de Regio klasse hieronder die onze uitbreidt Land klasse uit de vorige sectie:

openbare klasse Regio breidt uit Land implementeert Externalizable {private static final long serialVersionUID = 1L; privé String klimaat; privé dubbele populatie; // getters, setters @Override public void writeExternal (ObjectOutput out) gooit IOException {super.writeExternal (out); out.writeUTF (klimaat); } @Override public void readExternal (ObjectInput in) gooit IOException, ClassNotFoundException {super.readExternal (in); this.climate = in.readUTF (); }}

Hier hebben we twee extra eigenschappen toegevoegd en de eerste geserialiseerd.

Let daar op we hebben ook gebeld super.writeExternal (uit), super.readExternal (in) binnen serializer-methoden om ook de velden van de bovenliggende klassen op te slaan / te herstellen.

Laten we de unit-test uitvoeren met de volgende gegevens:

Regio r = nieuwe regio (); r.setCode (374); r.setName ("Armenië"); r.setClimate ("Middellandse Zee"); r.setPopulation (120.000);

Hier is het gedeserialiseerde object:

Regio {country = "Land {name =" Armenië ', code = 374}' klimaat = "Middellandse Zee", bevolking = null}

Let erop dat aangezien we de bevolking veld in Regio class, is de waarde van die eigenschap nul.

3. Uitwendig te maken vs Serialiseerbaar

Laten we de belangrijkste verschillen tussen de twee interfaces doornemen:

  • Verantwoordelijkheid voor serialisering

Het belangrijkste verschil hier is hoe we omgaan met het serialisatieproces. Wanneer een klas het java.io.Serializable interface, neemt de JVM de volledige verantwoordelijkheid voor het serialiseren van de klasse-instantie. In het geval van Extern aanpasbaar, het is de programmeur die voor het hele serialisatie- en ook het deserialisatieproces moet zorgen.

  • Use Case

Als we het hele object moeten serialiseren, is de Serialiseerbaar interface past beter. Aan de andere kant, voor aangepaste serialisatie kunnen we het proces besturen met Uitwendig te maken.

  • Prestatie

De java.io.Serializable interface maakt gebruik van reflectie en metadata waardoor de prestaties relatief traag zijn. Ter vergelijking: de Uitwendig te maken interface geeft u volledige controle over het serialisatieproces.

  • Leesvolgorde

Tijdens het gebruik Uitwendig te maken, is het verplicht om alle veldstatussen in de exacte volgorde te lezen zoals ze zijn geschreven. Anders krijgen we een uitzondering.

Als we bijvoorbeeld de leesvolgorde van de code en naam eigenschappen in de Land klasse A, eerste klasse java.io.EOFException zal worden gegooid.

Ondertussen is de Serialiseerbaar interface heeft die vereiste niet.

  • Aangepaste serialisering

We kunnen serialisering op maat bereiken met de Serialiseerbaar interface door het veld te markeren met voorbijgaand trefwoord. De JVM zal het specifieke veld niet serialiseren, maar het zal het veld optellen naar bestandsopslag met de standaardwaarde. Daarom is het een goede gewoonte om te gebruiken Uitwendig te maken in het geval van aangepaste serialisatie.

4. Conclusie

In deze korte gids voor het Uitwendig te maken interface bespraken we de belangrijkste kenmerken, voordelen en gedemonstreerde voorbeelden van eenvoudig gebruik. We hebben ook een vergelijking gemaakt met de Serialiseerbaar koppel.

Zoals gewoonlijk is de volledige broncode van de tutorial beschikbaar op GitHub.


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