Sérialisation Java


Java fournit un mécanisme de sérialisation d'objet. Dans ce mécanisme, un objet peut être représenté sous la forme d'une séquence d'octets, qui comprend les données de l'objet, des informations sur le type de l'objet et le type de données dans l'objet.

Après avoir écrit l'objet sérialisé dans le fichier, vous pouvez le lire à partir du fichier et le désérialiser, c'est-à-dire que les informations de type de l'objet, les données de l'objet et les données dans les types d'objet peuvent être utilisé pour créer de nouveaux objets en mémoire.

L'ensemble du processus est indépendant de la machine virtuelle Java (JVM), c'est-à-dire qu'un objet sérialisé sur une plate-forme peut désérialiser l'objet sur une plate-forme complètement différente.

Les classes ObjectInputStream et ObjectOutputStream sont des flux de données de haut niveau qui contiennent des méthodes de sérialisation et de désérialisation d'objets. La classe

ObjectOutputStream contient de nombreuses méthodes d'écriture pour écrire différents types de données, à l'exception d'une méthode particulière :

public final void writeObject(Object x) throws IOException

La méthode ci-dessus sérialise un objet et l'envoie au flux de sortie. La classe similaire ObjectInputStream contient la méthode suivante pour désérialiser un objet :

public final Object readObject() throws IOException, 
                                 ClassNotFoundException

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

Pour démontrer le fonctionnement de la sérialisation en Java, j'utiliserai la classe Employee mentionnée dans le didacticiel précédent. Supposons que nous définissions la classe Employee suivante, qui implémente l'interface Serialisable.

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("Mailing a check to " + 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'objet java.io.Seriallessly.

Toutes les propriétés de cette classe doivent être sérialisables. Si une propriété n'est pas sérialisable, elle doit être marquée comme éphémère.

Si vous souhaitez savoir si une classe standard Java est sérialisable, consultez la documentation de cette classe. Vérifier si une instance d'une classe peut être sérialisée est très simple. Vérifiez simplement si la classe implémente l'interface java.io.Seriallessly.


Objet sérialisé

La classe ObjectOutputStream est utilisée pour sérialiser un objet. L'exemple SerializeDemo suivant instancie un objet Employee et sérialise l'objet dans un fichier.

Une fois le programme exécuté, un fichier nommé employe.ser est créé. Le programme ne produit aucun résultat, 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, selon la convention standard de Java, le fichier reçoit une extension .ser.

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("Serialized data is saved in /tmp/employee.ser");
      }catch(IOException i)
      {
          i.printStackTrace();
      }
   }
}

Objet de désérialisation

Le programme DeserializeDemo ci-dessous instancie la désérialisation et /tmp/employee.ser stocke l'objet Employee.

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("Employee class not found");
         c.printStackTrace();
         return;
      }
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + e.name);
      System.out.println("Address: " + e.address);
      System.out.println("SSN: " + e.SSN);
      System.out.println("Number: " + e.number);
    }
}

Les résultats de compilation et d'exécution du programme ci-dessus sont les suivants :

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

Les points suivants doivent être notés ici :

Le bloc de code try/catch dans readObject () tente d'intercepter l'exception ClassNotFoundException. Pour que la JVM puisse désérialiser un objet, il doit s'agir d'une classe capable de trouver le bytecode. Si la JVM ne parvient pas à trouver la classe lors de la désérialisation de l'objet, une ClassNotFoundException est levée.

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

Lorsque l'objet est sérialisé, la valeur de l'attribut SSN est 111222333, mais comme l'attribut est éphémère, la valeur n'est pas envoyée au flux de sortie. Ainsi, l'attribut SSN de l'objet Employee après désérialisation est 0.