« Tu te souviendras qu'aujourd'hui nous avons étudié l'enregistrement d'objets et leur lecture à l'aide de fichiers ? »
« Oui, on les a juste enregistrés dans un flux de sortie, puis lus dans un flux d'entrée. »
« Très bien, Amigo. Il est bon de savoir que tu remarques ces détails. Réussiras-tu à compléter le code afin qu'il enregistre et lise depuis un fichier ? »
« Compléter quoi !? On déclare un FileInputStream et un FileOutputStream, et on les passe aux méthodes save et load. Il n'y a rien de compliqué ici. Super simple. »
« Je suis content pour toi. Maintenant, un nouveau sujet : la sérialisation. »
La sérialisation ressemble beaucoup à ce que nous venons de faire, mais en bien plus cool et directement intégré dans la machine Java. La machine Java peut stocker et charger ses objets. Elle n'a même pas besoin de méthodes d'enregistrement/chargement pour le faire : Tous les objets sont stockés à l'intérieur de la machine Java, et elle y a pleinement accès. »
Il nous suffit de prendre l'objet et de l'enregistrer dans un flux, puis de lire à partir d'un flux :
public static void main(String[] args) throws Exception
{
Cat cat = new Cat();
//Save a cat to file
FileOutputStream fileOutput = new FileOutputStream("cat.dat");
ObjectOutputStream outputStream = new ObjectOutputStream(fileOutput);
outputStream.writeObject(cat);
fileOutput.close();
outputStream.close();
//Load a cat from file
FileInputStream fiStream = new FileInputStream("cat.dat");
ObjectInputStream objectStream = new ObjectInputStream(fiStream);
Object object = objectStream.readObject();
fiStream.close();
objectStream.close();
Cat newCat = (Cat)object;
}
« C'est tout ? »
« Exactement. Il existe un mécanisme de sérialisation massif et très complexe qui nous permet d'enregistrer dans un flux et de lire depuis un flux pour quasiment tous les types de données. »
« Quasiment tous. Donc pas n'importe lesquels ? »
« Oui, le fait est que tous les objets n'ont la capacité inhérente d'être enregistrés. Certains objets ne stockent pas toutes leurs données en interne. Au lieu de cela, ils font simplement référence à d'autres objets et/ou sources de données. Par exemple, la console (System.in), un flux d'entrée (InputStream), et d'autres choses. »
C'est pourquoi les créateurs de Java ont inventé le marqueur d'interface spécial Serializable. On dit que c'est un marqueur, car il ne contient ni données ni méthodes. Il est seulement utilisé pour « marquer » des classes. Si nous estimons que notre classe stocke toutes ses données en interne, alors nous pouvons la marquer avec implements Serializable.
Voici un exemple de 'chat' qui prend en charge la sérialisation :
class Cat implements Serializable
{
public String name;
public int age;
public int weight;
}
Lorsque nous essayons de sérialiser (enregistrer) un objet, la machine Java vérifie s'il prend en charge la sérialisation : Est-ce qu'il implémente l'interface Serializable ? Si c'est le cas, elle enregistre l'objet. Dans le cas contraire, elle lève une exception pour indiquer que la sérialisation est impossible.
Ici, tu dois comprendre qu'un objet sérialisable ne doit être constitué que d'objets sérialisables.
« Tout cela me paraît logique. On ne peut pas enregistrer l'ensemble sans enregistrer ses parties. »
« Exactement. »
« Et qu'en est-il des int, String et ArrayList ? »
« Ils prennent tous en charge la sérialisation. Les créateurs de Java ont fait tout le nécessaire pour que ce soit possible. Il ne devrait pas y avoir de problèmes ici. »
De plus, le type d'un objet est enregistré lorsque l'objet est sérialisé. Maintenant, tu peux enregistrer une référence à un objet Cat dans une variable Object. Tout sera sérialisé et désérialisé sans le moindre pépin.
« Désérialisé ? »
« La désérialisation est le processus inverse de la sérialisation : la lecture et la reconstruction d'un objet à partir d'un flux/fichier. »
« Ah, alors je n'ai pas d'autres questions. »
GO TO FULL VERSION