Java: Que peut-on et que ne peut-on pas sérialiser?

Si l’interface Serializable est simplement une interface marqueur utilisée pour transmettre une sorte de méta-données sur les classes en Java, je suis un peu confus:

Après avoir lu le processus de l’algorithme de sérialisation java (métadonnées de bas en haut, puis données d’instance réelles de haut en bas), je ne comprends pas vraiment quelles données ne peuvent pas être traitées via cet algorithme.

En bref et formel:

  1. Quelles données peuvent provoquer l’ NotSerializableException ?
  2. Comment devrais-je savoir que je ne suis pas censé append la clause implements Serializable pour ma classe?

Lorsque vous parlez de NotSerializableException elle est lancée lorsque vous souhaitez sérialiser un object qui n’a pas été marqué comme Serializable . C’est tout, même si vous étendez une classe non sérialisable et ajoutez une interface Serializable , tout se passe parfaitement.

Il n’y a pas de données qui ne peuvent pas être sérialisées.

Tout d’abord, si vous ne prévoyez pas de sérialiser une instance de votre classe, vous n’avez même pas besoin de penser à la sérialiser. N’implémentez que ce dont vous avez besoin et n’essayez pas de rendre votre classe sérialisable juste pour le plaisir de le faire.

Si votre object a une référence (transitive ou directe) à un object non sérialisable et que cette référence n’est pas marquée avec le mot clé transient , votre object ne sera pas sérialisable.

En règle générale, il est inutile de sérialiser des objects qui ne peuvent pas être réutilisés lorsqu’ils sont désérialisés ultérieurement ou ailleurs. Cela peut être dû au fait que l’état de l’object n’a de signification qu’ici et maintenant (s’il contient une référence à un thread en cours d’exécution, par exemple), ou s’il utilise des ressources telles qu’un socket, une connexion à une firebase database ou quelque chose du genre. Un grand nombre d’objects ne représentent pas de données et ne devraient pas être sérialisables.

Sérialisation – Transforme les données en stream d’octets

Désérialisation – Transforme un stream d’octets en une copie de l’object d’origine.

Sérialisation en JAVA : – Serializable est un marqueur qui indique à la JVM qu’elle peut écrire l’état de l’object dans un stream (en gros lire tous les membres et écrire leur état dans un stream, sur disque ou autre). Le mécanisme par défaut est un format binary. Vous pouvez également l’utiliser pour cloner des éléments, ou conserver un état entre les invocations, envoyer des objects sur le réseau, etc.

Transitoire: –

Le mot-clé transitoire en Java indique que la variable ne doit pas être sérialisée. Par défaut, toutes les variables de l’object sont converties en état persistant. Dans certains cas, vous souhaiterez peut-être éviter de conserver certaines variables, car vous n’avez pas besoin de les transférer sur le réseau. Vous pouvez donc déclarer ces variables comme transitoires. Si la variable est déclarée transitoire, elle ne sera pas persistée. C’est le but principal du mot clé transitoire.

Le mot-clé transitoire en java est comparativement moins commun que tout autre mot-clé comme volatile. Étant donné que le mot-clé transitoire est moins fréquent, il devient encore plus important de comprendre son utilisation correcte. Dans un mot-clé, le mot-clé transitoire est utilisé dans le processus de sérialisation pour empêcher la sérialisation de toute variable. Par conséquent, si vous ne sérialisez pas un champ, vous pouvez simplement le déclarer comme transitoire et ne pas le sérialiser.

Tout ce que votre classe Serializable possède qui n’est pas Serializable jettera cette exception. Vous pouvez l’éviter en utilisant le mot clé transient .

Les composants courants et les threads sont des exemples courants de choses que vous ne pouvez pas sérialiser. Si vous y réfléchissez, cela a du sens car vous ne pourriez jamais les désérialiser et en avoir le sens.

Tous les types de données primitifs et les classes s’étendent soit directement Serializable ,

 class MyClass extends Serializable{ } 

ou indirectement,

 class MyClass extends SomeClass{ } 

SomeClass implémente Serializable.

peut être sérialisé. Tous les champs d’une classe sérialisable sont sérialisés à l’exception des champs marqués transient . Si une classe sérialisable contient un champ qui n’est pas sérialisable (non primitif et ne s’étend pas depuis une interface sérialisable), une NotSerializableException sera levée.

Réponse à la deuxième question: Comme l’a dit @JB Nizet. Si vous allez écrire l’instance d’une classe dans un stream, puis ne la marquez que comme étant Serializable, sinon ne marquez jamais une classe Serializable.

Vous devez gérer la sérialisation de vos propres objects.

Java gérera les types de données primitifs pour vous.

Plus d’infos: http://www.tutorialspoint.com/java/java_serialization.htm

NotSerialisable exception NotSerialisable est levée lorsque quelque chose dans votre sérialisable est marqué comme sérialisable. Un tel cas peut être:

 class Super{} class Sub implements Serializable { Super super; 

Ici, super n’est pas mentionné en tant que sérialisable et lancera donc NotSerializableException .

Après avoir lu le processus de l’algorithme de sérialisation java (métadonnées de bas en haut, puis données d’instance réelles de haut en bas), je ne comprends pas vraiment quelles données ne peuvent pas être traitées via cet algorithme.

La réponse à cela est que certaines classes au niveau du système, telles que Thread, OutputStream et ses sous-classes, ne sont pas sérialisables. Très bien expliqué sur les documents Oracle: http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html

Ci-dessous le résumé:

D’autre part, certaines classes au niveau du système telles que Thread, OutputStream et ses sous-classes et Socket ne sont pas sérialisables. En effet, cela n’aurait aucun sens s’ils l’étaient. Par exemple, le thread en cours d’exécution dans ma JVM utiliserait la mémoire de mon système. La persister et essayer de l’exécuter dans votre machine virtuelle n’aurait aucun sens.

Plus concrètement, aucun object ne peut être sérialisé (via le mécanisme intégré de Java) à moins que sa classe implémente l’interface Serializable. Etre une instance d’une telle classe n’est toutefois pas une condition suffisante: pour qu’un object soit sérialisé correctement, il doit également être vrai que toutes les références non transitoires qu’il contient doivent être nulles ou faire référence à des objects sérialisables. (Notez qu’il s’agit d’une condition récursive.) Les valeurs primitives, les valeurs NULL et les variables transitoires ne posent aucun problème. Les variables statiques n’appartenant pas à des objects individuels, elles ne posent donc pas de problème non plus.

Certaines classes courantes sont sûres pour la sérialisation. Les chaînes sont probablement les plus remarquables ici, mais toutes les classes d’encapsulation pour les types primitifs sont également sûres. Les tableaux de primitives sont sérialisables de manière fiable. Les tableaux de types de référence peuvent être sérialisés si tous leurs éléments peuvent être sérialisés.

Question – Quelles données peuvent provoquer l’exception NotSerializableException?

Réponse – En Java, nous sérialisons un object (l’instance d’une classe Java qui a déjà implémenté l’ interface Serializable ). Il est donc très clair que si une classe n’a pas implémenté l’ interface Serializable , elle ne peut pas être sérialisée (dans ce cas, une exception NotSerializableException sera levée).

L’interface Serializable n’est qu’une interface marqueur , en quelque sorte nous pouvons dire que c’est juste un tampon sur une classe et que cela indique simplement à JVM que cette classe peut être sérialisée.


Question – Comment puis-je savoir que je ne suis pas censé append la clause implerial Serializable pour ma classe?

Réponse – Tout dépend de vos besoins.

  1. If you want to store the *Object* in a database, you can serialize it to a sequence of byte and can store it in the database as persistent data. 2. You can serialize your *Object* to be used by other JVM working on different machine.