10.2Sérialisation
10.2.1 – Principe
La sérialisation est le processus de conversion d'un objet Java en un flux d'octets pour le stocker dans un fichier ou l'envoyer sur un réseau. La désérialisation est le processus inverse qui reconstruit l'objet à partir du flux.
🔑 Interface Serializable
Pour qu'une classe soit sérialisable, elle doit implémenter l'interface Serializable. Cette interface est un marqueur (marker interface) : elle n'a pas de méthodes à implémenter.
Exemple : Classe sérialisable
import java.io.Serializable;
public class Personne implements Serializable {
private static final long serialVersionUID = 1L; // ID de version
private String nom;
private int age;
private transient String motDePasse; // transient : ne sera pas sérialisé
public Personne(String nom, int age) {
this.nom = nom;
this.age = age;
}
// Getters et setters...
}
🆔 serialVersionUID
Le serialVersionUID est un identifiant de version utilisé par Java pour vérifier la compatibilité entre la version de la classe utilisée pour sérialiser un objet et celle utilisée pour le désérialiser. C'est une constante static final long.
Pourquoi utiliser serialVersionUID ?
Si vous ne déclarez pas explicitement un serialVersionUID, Java en génère un automatiquement basé sur la structure de la classe. Si vous modifiez la classe (ajout/suppression d'attributs, changement de méthodes), le serialVersionUID généré change, ce qui peut causer des erreurs lors de la désérialisation d'objets sérialisés avec une version antérieure.
Exemple : Classe avec serialVersionUID
import java.io.Serializable;
public class Personne implements Serializable {
private static final long serialVersionUID = 1L; // ID de version
private String nom;
private int age;
private String email; // Nouvel attribut ajouté plus tard
public Personne(String nom, int age) {
this.nom = nom;
this.age = age;
}
// Getters et setters...
}
- Le
serialVersionUIDest une constantestatic final long - Il identifie la version de la classe pour la sérialisation
- Si le
serialVersionUIDde la classe désérialisée ne correspond pas à celui de l'objet sérialisé, uneInvalidClassExceptionest levée - En déclarant explicitement un
serialVersionUID, vous pouvez contrôler la compatibilité entre versions
Générer un serialVersionUID
Vous pouvez générer un serialVersionUID de plusieurs façons :
- Manuellement : Utiliser
1Lpour commencer, puis l'incrémenter à chaque changement incompatible - Avec l'IDE : La plupart des IDE (IntelliJ, Eclipse) peuvent générer automatiquement un
serialVersionUID - Avec la commande : Utiliser
serialveren ligne de commande
- Toujours déclarer explicitement un
serialVersionUIDdans les classes sérialisables - Commencez avec
1Let incrémentez-le seulement si vous faites des changements incompatibles - Les changements compatibles (ajout d'attributs avec valeurs par défaut) ne nécessitent généralement pas de changer le
serialVersionUID - Les changements incompatibles (suppression d'attributs, changement de types) nécessitent un nouveau
serialVersionUID
🚫 Mot-clé transient
Le mot-clé transient indique qu'un attribut ne doit pas être sérialisé (utile pour les mots de passe, etc.).
public class Personne implements Serializable {
private static final long serialVersionUID = 1L;
private String nom;
private int age;
private transient String motDePasse; // Ne sera pas sérialisé
// ...
}
transient ne sont pas sauvegardés lors de la sérialisation et seront null (ou valeur par défaut) après la désérialisation.
10.2.2 – Exemple simple
Voici un exemple complet de sérialisation et désérialisation d'un objet.
💾 Sérialisation
Exemple : Sérialiser un objet
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
Personne personne = new Personne("Alice", 25);
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("personne.dat"))) {
oos.writeObject(personne);
System.out.println("Objet sérialisé avec succès");
} catch (IOException e) {
System.out.println("Erreur : " + e.getMessage());
}
📂 Désérialisation
Exemple : Désérialiser un objet
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("personne.dat"))) {
Personne p = (Personne) ois.readObject();
System.out.println("Nom : " + p.getNom());
System.out.println("Âge : " + p.getAge());
} catch (IOException | ClassNotFoundException e) {
System.out.println("Erreur : " + e.getMessage());
}
💡 Points clés à retenir
- Serializable : Interface marqueur pour rendre une classe sérialisable
- serialVersionUID : Identifiant de version pour la compatibilité entre versions de la classe
- transient : Attributs non sérialisés
- ObjectOutputStream : Pour sérialiser
- ObjectInputStream : Pour désérialiser
- ClassNotFoundException : Peut être levée lors de la désérialisation
- InvalidClassException : Peut être levée si le serialVersionUID ne correspond pas
serialVersionUID explicite dans vos classes sérialisables. Cela vous donne un contrôle sur la compatibilité des versions et évite les erreurs inattendues lors de la désérialisation d'objets créés avec des versions antérieures de votre classe.