Achtergrond
Vanaf het begin van Java ontstond de noodzaak om objecten tussen sessies van applicaties op te slaan - ze over het netwerk te verzenden, in een database of op een schijf te schrijven. Hiervoor werd het Serializable-interface bedacht, dat het mogelijk maakte om objecten om te zetten in een stroom van bytes en vice versa (serialisatie en deserialisatie).
Probleem
Als een klasse het Serializable-interface niet implementeert, zal een poging om een exemplaar te serialiseren een uitzondering veroorzaken. Bovendien slaat serialisatie niet alleen de waarden van velden op, maar ook hun toestand, zodat een onjuiste implementatie kan leiden tot onverwachte kwetsbaarheden, fouten bij het herstellen van een object of zelfs gegevensverlies.
Oplossing
Het Serializable-interface is een marker-interface, dat wil zeggen dat het geen methoden bevat. Voor correcte serialisatie is het raadzaam om serialVersionUID expliciet op te geven, evenals het trefwoord transient voor velden die niet geserialiseerd moeten worden.
Codevoorbeeld:
import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private String username; private transient String password; // wordt niet geserialiseerd public User(String username, String password) { this.username = username; this.password = password; } }
Belangrijke kenmerken:
Is het verplicht om het veld serialVersionUID expliciet te declareren?
Nee, dat is niet verplicht, maar als het niet wordt gedeclareerd, wordt het automatisch gegenereerd. Bij wijzigingen in de klasse kan het herstellen van de oude geserialiseerde versie leiden tot InvalidClassException. Daarom is het beter om dit veld altijd expliciet op te geven.
Worden statische velden geserialiseerd?
Nee, alleen niet-statische (instant) velden worden geserialiseerd. Statische velden behoren tot de klasse en niet tot het object, en daarom worden hun waarden tijdens serialisatie en deserialisatie niet opgeslagen of hersteld.
Kan een object worden geserialiseerd waarvan de velden geen Serializable implementeren?
Nee, als ten minste één niet-statisch veld niet serializeerbaar is en niet als transient is gedeclareerd, zal een poging tot serialisatie een NotSerializableException veroorzaken.
In een applicatie voor het cachen van gebruikers werd serialVersionUID niet opgegeven, en bij het aanpassen van de code werd de structuur van de User-klasse gewijzigd. Bij het starten van de applicatie ontstond er een InvalidClassException en gingen alle geserialiseerde gegevens verloren.
Voordelen:
Nadelen:
In een vergelijkbaar project werd serialVersionUID altijd expliciet opgegeven en werden alle velden die niet geserialiseerd moesten worden, transient gemaakt. Hierdoor konden geserialiseerde objecten succesvol worden geladen na het wijzigen van een onbeduidende structuur van de klasse.
Voordelen:
Nadelen: