Introduction
Serialization is de conversie van de status van een object naar een bytestroom; deserialisatie doet het tegenovergestelde. Anders gezegd, serialisatie is de conversie van een Java-object in een statische stroom (sequentie) van bytes die vervolgens kan worden opgeslagen in een database of overgedragen over een netwerk.
serialisatie en deserialisatie
het serialisatieproces is instantieonafhankelijk, d.w.z., objecten kunnen op het ene platform worden geserialiseerd en op het andere worden gedeserialiseerd. Klassen die in aanmerking komen voor serialisatie moeten een speciale marker interface serialiseerbaar implementeren.
zowel ObjectInputStream als ObjectOutputStream zijn klassen op hoog niveau die respectievelijk java.io.InputStream en java.io.OutputStream uitbreiden. ObjectOutputStream kan primitieve types en grafieken van objecten schrijven naar een OutputStream als een stroom van bytes. Deze streams kunnen vervolgens worden gelezen met behulp van ObjectInputStream.,
De belangrijkste methode in ObjectOutputStream is:
public final void writeObject(Object o) throws IOException;
die een serialiseerbaar object neemt en converteert naar een reeks (stream) van bytes. Ook de belangrijkste methode in ObjectInputStream is:
public final Object readObject() throws IOException, ClassNotFoundException;
die een stroom van bytes kan lezen en converteren naar een Java-object. Dit kan dan teruggeworpen worden naar het oorspronkelijke object.
laten we serialisatie illustreren met een Persoonsklasse. Merk op dat statische velden behoren tot een klasse (in tegenstelling tot een object) en zijn niet geserialiseerd., Merk ook op dat we het trefwoord transient kunnen gebruiken om klassenvelden te negeren tijdens serialisatie:
public class Person implements Serializable { private static final long serialVersionUID = 1L; static String country = "ITALY"; private int age; private String name; transient int height; // getters and setters}
De test hieronder toont een voorbeeld van het opslaan van een object van het type persoon in een lokaal bestand lees dan deze waarde terug in:
We gebruikten ObjectOutputStream voor het opslaan van de status van dit object in een bestand met behulp van FileOutputStream. Het bestand ” uw bestand.txt” wordt aangemaakt in de projectdirectory. Dit bestand wordt dan geladen met behulp van Fileputstream. ObjectInputStream pikt deze stroom op en zet het om in een nieuw object genaamd p2.,
ten slotte testen we de status van het geladen object, en het komt overeen met de status van het oorspronkelijke object.
merk op dat het geladen object expliciet naar een Persoonstype moet worden gegoten.
java serialization Caveats
Er zijn enkele caveats die betrekking hebben op de serialisatie in Java.
3.1. Overerving en compositie
wanneer een klasse de Java.io.Serialisable interface implementeert, zijn alle subklassen ook serialiseerbaar., Integendeel, als een object een verwijzing naar een ander object heeft, moeten deze objecten de Serialiseerbare interface afzonderlijk implementeren, anders wordt een NotSerializableException gegooid:
public class Person implements Serializable { private int age; private String name; private Address country; // must be serializable too}
als een van de velden in een serialiseerbaar object bestaat uit een array van objecten, dan moeten al deze objecten ook serialiseerbaar zijn, of anders wordt een NotSerializableException gegooid.
3.2. Seriële versie UID
de JVM associeert een versienummer (lang) met elke serialiseerbare klasse., Het wordt gebruikt om te controleren of de opgeslagen en geladen objecten dezelfde attributen hebben en dus compatibel zijn bij serialisatie.
dit getal kan automatisch worden gegenereerd door de meeste IDEs en is gebaseerd op de klassenaam, de attributen en de bijbehorende toegangsmodifiers. Eventuele wijzigingen resulteren in een ander nummer en kan leiden tot een Ongeldigclassexceptie.
als een serialiseerbare Klasse geen serialVersionUID declareert, zal de JVM er automatisch een genereren tijdens het uitvoeren., Het wordt echter sterk aanbevolen dat elke klasse zijn serialVersionUID declareert omdat de gegenereerde compiler afhankelijk is en dus kan resulteren in onverwachte ongeldige Klassenexcepties.
3.3. Aangepaste serialisatie in Java
Java specificeert een standaard manier waarop objecten geserialiseerd kunnen worden. Java-klassen kunnen dit standaardgedrag overschrijven. Aangepaste serialisatie kan bijzonder nuttig zijn wanneer het proberen om een object dat een aantal unserialisable attributen heeft serialiseren., Dit kan gedaan worden door middel van twee methoden in de klasse die we willen serialiseren:
private void writeObject(ObjectOutputStream out) throws IOException;
en
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Met deze methoden, kunnen we het serialiseren van die unserializable attributen in andere vormen die kan worden toegepast:
public class Address { private int houseNumber; // setters and getters}
De volgende unit test test dit aangepaste serienummers:
In deze code, zien we hoe op te slaan sommige unserializable kenmerken door serienummer op te geven Adres met aangepaste serienummers. Merk op dat we de unserialisable attributen als voorbijgaand moeten markeren om de Notserializableexceptie te vermijden.,
conclusie
in deze korte handleiding hebben we Java-serialisatie bekeken, belangrijke dingen besproken om in gedachten te houden en hebben we laten zien hoe aangepaste serialisatie te doen.