La sérialisation est un mécanisme de conversion de l'état d'un objet en un flux d'octets. La désérialisation est le processus inverse dans lequel le flux d'octets est utilisé pour recréer l'objet Java réel en mémoire. Ce mécanisme est utilisé pour conserver l'objet.
Le flux d'octets créé est indépendant de la plate-forme. Ainsi, l'objet sérialisé sur une plateforme peut être désérialisé sur une autre plateforme. Pour rendre un objet Java sérialisable, nous implémentons le java.io.Sérialisable interface. La classe ObjectOutputStream contient writeObject() méthode de sérialisation d’un objet.
public final void writeObject(Object obj) throws IOException>
La classe ObjectInputStream contient readObject() méthode pour désérialiser un objet.
public final Object readObject() throws IOException, ClassNotFoundException>
Avantages de la sérialisation
- Pour enregistrer/conserver l’état d’un objet.
- Faire voyager un objet à travers un réseau.

Seuls les objets des classes qui implémentent java.io.Sérialisable interface. Sérialisable est un interface de marqueur (n'a pas de données membres ni de méthode). Il est utilisé pour marquer les classes Java afin que les objets de ces classes puissent acquérir certaines capacités. D'autres exemples d'interfaces de marqueurs sont : - Clonable et distant.
Points à retenir
1. Si une classe parent a implémenté l'interface Serialisable, la classe enfant n'a pas besoin de l'implémenter, mais l'inverse n'est pas vrai.
2. Seules les données membres non statiques sont enregistrées via le processus de sérialisation.
3. Les données membres statiques et les données membres transitoires ne sont pas enregistrées via le processus de sérialisation. Donc, si vous ne souhaitez pas enregistrer la valeur d'une donnée membre non statique, rendez-la transitoire.
4. Le constructeur d'objet n'est jamais appelé lorsqu'un objet est désérialisé.
5. Les objets associés doivent implémenter l'interface sérialisable. Exemple :
class A implements Serializable{ // B also implements Serializable // interface. B ob=new B(); }> SerialVersionUID Le runtime de sérialisation associe un numéro de version à chaque classe sérialisable appelé SerialVersionUID, qui est utilisé lors de la désérialisation pour vérifier que l'expéditeur et le destinataire d'un objet sérialisé ont chargé des classes pour cet objet qui sont compatibles en ce qui concerne la sérialisation. Si le destinataire a chargé une classe pour l'objet qui a un UID différent de celui de la classe de l'expéditeur correspondant, la désérialisation entraînera un Exception de classe invalide .
Une classe Serialisable peut déclarer explicitement son propre UID en déclarant un nom de champ. Il doit être statique, définitif et de type long. c'est-à-dire ANY-ACCESS-MODIFIER statique final long serialVersionUID=42L ; Si une classe sérialisable ne déclare pas explicitement un serialVersionUID, le runtime de sérialisation en calculera un par défaut pour cette classe en fonction de divers aspects de la classe, comme décrit dans la spécification de sérialisation d'objets Java. Cependant, il est fortement recommandé que toutes les classes sérialisables déclarent explicitement la valeur SerialVersionUID, car son calcul est très sensible aux détails de la classe qui peuvent varier en fonction des implémentations du compilateur. Tout changement de classe ou utilisation d'un identifiant différent peut affecter les données sérialisées. Il est également recommandé d'utiliser un modificateur privé pour l'UID car il n'est pas utile en tant que membre hérité. sérialiste Le Serialver est un outil fourni avec JDK. Il est utilisé pour obtenir le numéro SerialVersionUID pour les classes Java.
Vous pouvez exécuter la commande suivante pour obtenir SerialVersionUID Serialver [-classpath classpath] [-show] [classname…]
Exemple 1:
Java
// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Demo>implements> java.io.Serializable> {> >public> int> a;> >public> String b;> >// Default constructor> >public> Demo(>int> a, String b)> >{> >this>.a = a;> >this>.b = b;> >}> }> class> Test> {> >public> static> void> main(String[] args)> >{> >Demo object =>new> Demo(>1>, 'geeksforgeeks');> >String filename = 'file.ser';> > >// Serialization> >try> >{> >//Saving of object in a file> >FileOutputStream file =>new> FileOutputStream(filename);> >ObjectOutputStream out =>new> ObjectOutputStream(file);> > >// Method for serialization of object> >out.writeObject(object);> > >out.close();> >file.close();> > >System.out.println('Object has been serialized');> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> >Demo object1 =>null>;> >// Deserialization> >try> >{> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream(filename);> >ObjectInputStream in =>new> ObjectInputStream(file);> > >// Method for deserialization of object> >object1 = (Demo)in.readObject();> > >in.close();> >file.close();> > >System.out.println('Object has been deserialized ');> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> > >catch>(ClassNotFoundException ex)> >{> >System.out.println('ClassNotFoundException is caught');> >}> >}> }> |
>
>
Sortir :
Object has been serialized Object has been deserialized a = 1 b = geeksforgeeks>
Exemple 2 :
Java
// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Emp>implements> Serializable {> private> static> final> long> serialversionUID => >129348938L;> >transient> int> a;> >static> int> b;> >String name;> >int> age;> >// Default constructor> public> Emp(String name,>int> age,>int> a,>int> b)> >{> >this>.name = name;> >this>.age = age;> >this>.a = a;> >this>.b = b;> >}> }> public> class> SerialExample {> public> static> void> printdata(Emp object1)> >{> >System.out.println('name = ' + object1.name);> >System.out.println('age = ' + object1.age);> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> public> static> void> main(String[] args)> >{> >Emp object =>new> Emp('ab',>20>,>2>,>1000>);> >String filename = 'shubham.txt';> >// Serialization> >try> {> >// Saving of object in a file> >FileOutputStream file =>new> FileOutputStream> >(filename);> >ObjectOutputStream out =>new> ObjectOutputStream> >(file);> >// Method for serialization of object> >out.writeObject(object);> >out.close();> >file.close();> >System.out.println('Object has been serialized
'> >+ 'Data before Deserialization.');> >printdata(object);> >// value of static variable changed> >object.b =>2000>;> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >object =>null>;> >// Deserialization> >try> {> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream> >(filename);> >ObjectInputStream in =>new> ObjectInputStream> >(file);> >// Method for deserialization of object> >object = (Emp)in.readObject();> >in.close();> >file.close();> >System.out.println('Object has been deserialized
'> >+ 'Data after Deserialization.');> >printdata(object);> >// System.out.println('z = ' + object1.z);> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >catch> (ClassNotFoundException ex) {> >System.out.println('ClassNotFoundException' +> >' is caught');> >}> >}> }> |
>
>
Sortir:
Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000>
Description de la sortie : vous avez constaté lors de la désérialisation de l'objet que les valeurs de a et b ont changé. La raison étant que a était marqué comme transitoire et b était statique.
En cas de variables transitoires : - Une variable définie avec le mot-clé transient n'est pas sérialisée pendant le processus de sérialisation. Cette variable sera initialisée avec la valeur par défaut lors de la désérialisation. (par exemple : pour les objets, c'est nul, pour les int, c'est 0).
En cas de Variables statiques : - Une variable définie avec le mot-clé static n'est pas sérialisée pendant le processus de sérialisation. Cette variable sera chargée avec la valeur actuelle définie dans la classe lors de la désérialisation.
Transitoire vs Final :
final les variables participeront à la sérialisation directement par leurs valeurs.
Par conséquent, déclarer une variable finale comme transitoire ne sert à rien.
//le compilateur attribue la valeur à la variable finale
exemple:
final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->10 car x est final. System.out.println(y);//20>
Exemple 3 :
Java
boucle infinie
//java code for final with transient> import> java.io.*;> class> Dog>implements> Serializable{> >int> i=>10>;> >transient> final> int> j=>20>;> }> class> GFG {> >public> static> void> main (String[] args)>throws> IOException,ClassNotFoundException> >{> >Dog d1=>new> Dog();> >//Serialization started> >System.out.println(>'serialization started'>);> >FileOutputStream fos=>new> FileOutputStream(>'abc.ser'>);> >ObjectOutputStream oos=>new> ObjectOutputStream(fos);> >oos.writeObject(d1);> >System.out.println(>'Serialization ended'>);> > >//Deserialization started> >System.out.println(>'Deserialization started'>);> >FileInputStream fis=>new> FileInputStream(>'abc.ser'>);> >ObjectInputStream ois=>new> ObjectInputStream(fis);> >Dog d2=(Dog) ois.readObject();> >System.out.println(>'Deserialization ended'>);> >System.out.println(>'Dog object data'>);> >//final result> >System.out.println(d2.i+>' '> +d2.j);> >}> }> |
>
>Sortir
serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>