Historique de la question
Depuis le début de l'existence de Java, il a été nécessaire de sauvegarder des objets entre les sessions de travail des applications - transmettre sur le réseau, enregistrer dans une base de données ou sur un disque. Pour cela, l'interface Serializable a été inventée, permettant de convertir des objets en flux d'octets et vice versa (sérialisation et désérialisation).
Problème
Si une classe n'implémente pas l'interface Serializable, la tentative de sérialiser son instance lancera une exception. De plus, la sérialisation sauvegarde non seulement les valeurs des champs, mais aussi leur état, de sorte qu'une mauvaise implémentation peut entraîner une vulnérabilité inattendue, des erreurs de restauration d'objet ou même une perte de données.
Solution
L'interface Serializable est un interface marqueur, c'est-à-dire qu'elle ne contient pas de méthodes. Pour une sérialisation correcte, il est conseillé de spécifier explicitement serialVersionUID, ainsi que d'utiliser le mot-clé transient pour les champs qui ne doivent pas être sérialisés.
Exemple de code :
import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private String username; private transient String password; // ne sera pas sérialisé public User(String username, String password) { this.username = username; this.password = password; } }
Caractéristiques clés :
Est-il nécessaire de déclarer explicitement le champ serialVersionUID ?
Non, ce n'est pas obligatoire, mais s'il n'est pas déclaré, il sera généré automatiquement. Cependant, en cas de modifications de la classe, la restauration de l'ancienne version sérialisée peut entraîner une InvalidClassException. Il est donc préférable de toujours déclarer explicitement ce champ.
Les champs statiques sont-ils sérialisés ?
Non, seuls les champs non-statiques (instance) sont sérialisés. Les champs statiques appartiennent à la classe et non à l'objet, et donc leurs valeurs ne sont pas sauvegardées ni restaurées lors de la sérialisation et de la désérialisation.
Peut-on sérialiser un objet dont les champs n'implémentent pas Serializable ?
Non, si au moins un champ non statique n'est pas sérialisable et n'est pas déclaré comme transient, la tentative de sérialisation lancera une NotSerializableException.
Dans une application de mise en cache des utilisateurs, le serialVersionUID n'a pas été précisé, et lors de la modification du code, la structure de la classe User a été changée. Au démarrage de l'application, une InvalidClassException s'est produite et toutes les données sérialisées ont été perdues.
Avantages :
Inconvénients :
Dans un projet similaire, le serialVersionUID était toujours spécifié explicitement et tous les champs non destinés à être sérialisés étaient déclarés transient. Grâce à cela, les objets sérialisés étaient chargés avec succès après des modifications mineures de la structure de la classe.
Avantages :
Inconvénients :