Serialisatie is een mechanisme om een object om te zetten in een stroom bytes voor latere opslag of overdracht. In Java werd serialisatie geïntroduceerd met het platform in versie 1.1 als onderdeel van de API, gezien de populariteit van gedistribueerde applicaties en de noodzaak om gegevens tussen hen uit te wisselen. Deze oplossing maakte het mogelijk om de overdracht van complexe objectgrafen tussen JVM's te vereenvoudigen en hun toestand op te slaan, waardoor het proces transparant werd voor de ontwikkelaar.
Het probleem van serialisatie is dat het noodzakelijk is om de dataintegriteit strikt te handhaven, versiebeheer van klassen te ondersteunen en complexere structuren (zoals grafen met cyclische referenties) correct te verwerken. Niet alle objecten zijn serialiseerbaar (bijvoorbeeld streams, sockets, OS-resources), en serialisatie vereist bijzondere aandacht voor beveiliging.
De oplossing is geïmplementeerd met behulp van de interface Serializable:
import java.io.*; class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private transient int age; // wordt niet geserialiseerd public Person(String name, int age) { this.name = name; this.age = age; } }
Met ObjectOutputStream en ObjectInputStream kan een object in een bestand worden geschreven en hersteld worden:
Person p = new Person("Alice", 30); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser")); oos.writeObject(p); // serialisatie ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser")); Person restored = (Person) ois.readObject();
Belangrijke kenmerken:
Serializable implementeren.transient worden niet geserialiseerd.Kan een object met een niet-serialiseerbaar veld worden geserialiseerd, zelfs als het niet wordt gebruikt?
Antwoord: Als het veld is gemarkeerd als transient, wordt het helemaal niet geserialiseerd, en het proces zal geen uitzondering veroorzaken, zelfs als het type het Serializable niet implementeert. Als het veld niet-serialiseerbaar is en niet transient, zal een NotSerializableException worden opgegooid.
Is statisch veld serialiseerbaar als de klasse Serializable implementeert?
Antwoord: Nee, statische velden worden niet geserialiseerd omdat ze toebehoren aan de klasse en niet aan de instantie. Alleen de toestand van de instantie wordt opgeslagen.
Wat gebeurd er als de klasse-structuur na serialisatie wordt gewijzigd (bijvoorbeeld een veld toevoegen of verwijderen)?
Antwoord: Als je de versie serialVersionUID specificeert, en de structuur is onverenigbaar veranderd, zal er bij deserialisatie een InvalidClassException optreden. Voor compatibiliteit worden serialisatie hints en handmatige controle van serialVersionUID gebruikt.
serialVersionUID en foutmeldingen ontvangen vanwege onverenigbare versies van klassenIngenieurs besloten een object te serialiseren zonder serialVersionUID toe te voegen en zonder velden die verwijzen naar OS-resources als transient te declareren. Na een update van de applicatie en de klasse trad er een InvalidClassException op en verloor het object zijn integriteit, waardoor deserialisatie niet meer werkte.
Voordelen:
Nadelen:
Voor serialisatie werd een draagbare klasse gemaakt met een expliciete serialVersionUID, en alle resource-velden zijn als transient gedeclareerd, en handmatige serialisatie controleert de belangrijke punten.
Voordelen:
Nadelen: