Sérialisation Java

La sérialisation Java est un processus de conversion d'un objet en un flux d'octets, afin que l'objet puisse être enregistré sur disque, transmis sur un réseau ou stocké en mémoire, puis désérialisé pour reconvertir le flux d'octets en objet.

En Java, la sérialisation est implémentée via l'interfacejava.io.Serializable. Cette interface n'a pas de méthodes ; c'est juste une interface de marquage utilisée pour indiquer qu'une classe peut être sérialisée.

Lorsque vous sérialisez un objet, vous l'encapsulez dans un fichier spécial qui peut être enregistré, transmis ou stocké. La désérialisation, quant à elle, ouvre ce fichier, lit les données sérialisées, puis les restaure sous forme d'objet pour une utilisation dans le programme.

La sérialisation est une méthode pour sauvegarder, transmettre et restaurer des objets. Elle permet de déplacer et de partager des objets entre différents ordinateurs, ce qui est très utile pour les systèmes distribués, le stockage de données et la communication multiplateforme.

Voici les concepts de base et l'utilisation de la sérialisation Java :

Implémentez l'interface Serializable : Pour rendre une classe sérialisable, vous devez faire en sorte que la classe implémente l'interface java.io.Serializable. Cela indique au compilateur Java que la classe peut être sérialisée, par exemple :

Exemple

import java.io.Serializable;

public class MyClass implements Serializable {
    // membres et méthodes de la classe
}

Sérialisation d'un objet :Utilisez la classe ObjectOutputStream pour sérialiser un objet en un flux d'octets. Voici un exemple simple :

Exemple

MyClass obj = new MyClass();
try {
    FileOutputStream fileOut = new FileOutputStream("object.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(obj);
    out.close();
    fileOut.close();
} catch (IOException e) {
    e.printStackTrace();
}

Le code ci-dessus sérialise l'objet obj dans un fichier nommé "object.ser".

Désérialisation d'un objet :Utilisez la classe ObjectInputStream pour désérialiser un objet à partir d'un flux d'octets. Voici un exemple simple :

Exemple

MyClass obj = null;
try {
    FileInputStream fileIn = new FileInputStream("object.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    obj = (MyClass) in.readObject();
    in.close();
    fileIn.close();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

Le code ci-dessus lit le flux d'octets à partir du fichier "object.ser" et le désérialise en un objet MyClass.

Les classes ObjectInputStream et ObjectOutputStream sont des flux de données de haut niveau qui contiennent des méthodes pour désérialiser et sérialiser des objets.

La classe ObjectOutputStream contient de nombreuses méthodes d'écriture pour écrire divers types de données, mais il existe une méthode spéciale qui fait exception :

public final void writeObject(Object x) throws IOException

La méthode ci-dessus sérialise un objet et l'envoie vers le flux de sortie. De même, la classe ObjectInputStream contient la méthode suivante pour désérialiser un objet :

public final Object readObject() throws IOException, ClassNotFoundException

Cette méthode récupère l'objet suivant dans le flux et désérialise l'objet. Sa valeur de retour est Object, donc vous devez la convertir vers le type de données approprié.

Exemple

Pour démontrer comment fonctionne la sérialisation en Java, je vais utiliser la classe Employee mentionnée dans un tutoriel précédent. Supposons que nous définissions la classe Employee comme suit ; cette classe implémente l'interface Serializable.

Code du fichier Employee.java :

public class Employee implements java.io.Serializable { public String name; public String address; public transient int SSN; public int number; public void mailCheck() { System.out.println("Envoi d'un chèque à " + name + " " + address); } }

Veuillez noter que pour qu'un objet d'une classe soit sérialisé avec succès, deux conditions doivent être remplies :

La classe doit implémenter l'interface java.io.Serializable.

Toutes les propriétés de la classe doivent être sérialisables. Si une propriété n'est pas sérialisable, elle doit être marquée comme transient.

Si vous voulez savoir si une classe Java standard est sérialisable, consultez la documentation de cette classe. Il est très simple de tester si une instance d'une classe peut être sérialisée ; il vous suffit de vérifier si la classe implémente l'interface java.io.Serializable.


Sérialisation d'un objet

La classe ObjectOutputStream est utilisée pour sérialiser un objet. L'exemple SerializeDemo ci-dessous instancie un objet Employee et sérialise cet objet dans un fichier.

Après l'exécution du programme, un fichier nommé employee.ser est créé. Le programme ne produit aucune sortie, mais vous pouvez comprendre ce que fait le programme en étudiant le code.

Remarque :Lors de la sérialisation d'un objet dans un fichier, la convention Java standard consiste à donner au fichier une extension .ser.

Code du fichier SerializeDemo.java :

import java.io.*; public class SerializeDemo { public static void main(String [] args) { Employee e = new Employee(); e.name = "Reyan Ali"; e.address = "Phokka Kuan, Ambehta Peer"; e.SSN = 11122333; e.number = 101; try { FileOutputStream fileOut = new FileOutputStream("/tmp/employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); System.out.printf("Les données sérialisées sont enregistrées dans /tmp/employee.ser"); }catch(IOException i) { i.printStackTrace(); } } }

Désérialisation d'un objet

Le programme DeserializeDemo ci-dessous démontre la désérialisation, avec /tmp/employee.ser stockant l'objet Employee.

Code du fichier DeserializeDemo.java :

import java.io.*; public class DeserializeDemo { public static void main(String [] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStream("/tmp/employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Employee) in.readObject(); in.close(); fileIn.close(); }catch(IOException i) { i.printStackTrace(); return; }catch(ClassNotFoundException c) { System.out.println("Classe Employee introuvable"); c.printStackTrace(); return; } System.out.println("Employé désérialisé..."); System.out.println("Nom : " + e.name); System.out.println("Adresse : " + e.address); System.out.println("SSN : " + e.SSN); System.out.println("Numéro : " + e.number); } }

Le résultat de compilation et d'exécution du programme ci-dessus est le suivant :

Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

Voici les points clés à noter :

Le bloc try/catch dans la méthode readObject() tente de capturer l'exception ClassNotFoundException. Pour que la JVM désérialise un objet, elle doit pouvoir trouver la classe du bytecode. Si la JVM ne trouve pas la classe lors de la désérialisation de l'objet, elle lève une exception ClassNotFoundException.

Notez que la valeur de retour de la méthode readObject() est convertie en une référence Employee.

Lorsque l'objet est sérialisé, la valeur de la propriété SSN est 111222333, mais comme cette propriété est transient, la valeur n'est pas envoyée dans le flux de sortie. Par conséquent, après la désérialisation, la propriété SSN de l'objet Employee est 0.

Autres extensions