Nous travaillons beaucoup avec la sérialisation et devoir spécifier une étiquette Serializable sur chaque objet que nous utilisons est une sorte de fardeau. Surtout lorsqu'il s'agit d'une classe tierce que nous ne pouvons pas vraiment changer.
La question est la suivante: puisque Serializable est une interface vide et que Java fournit une sérialisation robuste une fois que vous avez ajouté implements Serializable
- pourquoi n’ont-ils pas rendu tout sérialisable et c’est tout?
Qu'est-ce que je rate?
La sérialisation est semée d'embûches. La prise en charge automatique de la sérialisation de ce formulaire fait que les classes internes font partie de l’API publique (c’est pourquoi javadoc vous donne les formes persistantes des classes ).
Pour une persistance à long terme, la classe doit pouvoir décoder ce formulaire, ce qui limite les modifications que vous pouvez apporter à la conception de la classe. Cela casse l'encapsulation.
La sérialisation peut également entraîner des problèmes de sécurité. En étant capable de sérialiser n'importe quel objet auquel elle fait référence, une classe peut accéder à des données auxquelles elle ne pourrait normalement pas (en analysant les données d'octet résultantes).
Il existe d'autres problèmes, tels que la forme sérialisée des classes internes mal définie.
Rendre toutes les classes sérialisables aggraverait ces problèmes. Départ Effective Java Second Edition , en particulier Point 74: Implémentez judicieusement Serializable.
Je pense que les utilisateurs Java et .Net se sont trompés cette fois-ci. Ils auraient mieux fait de tout sérialiser par défaut. Il suffit de marquer les classes qui ne peuvent pas être sérialisées à la place.
Par exemple, dans Smalltalk (un langage créé dans les années 70), chaque objet est sérialisable par défaut. Je ne comprends pas pourquoi ce n'est pas le cas en Java, compte tenu du fait que la grande majorité des objets peuvent être sérialisés sans risque et que quelques-uns d'entre eux ne le sont pas.
Marquer un objet comme sérialisable (avec une interface) ne le rend pas magiquement sérialisable, il était sérialisable depuis le début , c'est juste que maintenant vous avez exprimé quelque chose que le système aurait pu trouver par lui-même, je ne vois donc vraiment bonne raison pour que la sérialisation soit comme elle est maintenant.
Je pense que c'était soit une mauvaise décision prise par les concepteurs, soit la sérialisation après coup, soit la plate-forme n'était jamais prête à effectuer la sérialisation par défaut sur tous les objets de manière cohérente et sécurisée.
Tout n'est pas vraiment sérialisable. Prenez une connexion de prise réseau, par exemple. Vous pouvez sérialiser les données/états de votre objet socket, mais l’essence d’une connexion active serait perdue.
Le rôle principal de Serializable en Java est de rendre, par défaut, tous les autres objets non sérialisables. La sérialisation est un mécanisme très dangereux, en particulier dans son implémentation par défaut. Par conséquent, à l'instar de l'amitié en C++, il est désactivé par défaut, même s'il est peu coûteux de rendre les choses sérialisables.
La sérialisation ajoute des contraintes et des problèmes potentiels car la compatibilité des structures n'est pas assurée. C'est bien qu'il soit désactivé par défaut.
Je dois admettre que j'ai vu très peu de classes non triviales où la sérialisation standard fait ce que je veux. Surtout dans le cas de structures de données complexes. Ainsi, l’effort que vous consacriez à la sérialisation de la classe annule le coût d’ajout de l’interface.
Pour certaines classes, en particulier celles qui représentent quelque chose de plus physique, comme un fichier, un socket, un thread ou une connexion à une base de données, la sérialisation d'instances n'a aucun sens. Pour beaucoup d'autres, la sérialisation peut être problématique car elle détruit les contraintes d'unicité ou vous oblige simplement à traiter des instances de différentes versions d'une classe, ce que vous ne souhaitez peut-être pas.
On pourrait soutenir qu'il aurait peut-être été préférable de rendre tout ce qui est sérialisable par défaut et de rendre les classes non sérialisables via une interface de mot clé ou de marqueur - mais ensuite, ceux qui devraient utiliser cette option n'y penseraient probablement pas. Ainsi, si vous avez besoin d'implémenter Serializable, une exception vous le dira.
Je pense que le but était de vous assurer, en tant que programmeur, que votre objet puisse être sérialisé.
Apparemment, tout était sérialisable dans certaines conceptions préliminaires, mais pour des raisons de sécurité et de précision, la conception finale s'est terminée comme nous le savons tous.
Ayant à déclarer explicitement que les instances d'une certaine classe sont Serializable, le langage vous oblige à réfléchir si vous le permettez. Pour les objets de valeur simples, la sérialisation est triviale, mais dans les cas plus complexes, vous devez vraiment réfléchir.
En vous appuyant simplement sur le support standard de la JVM pour la sérialisation, vous vous exposez à toutes sortes de problèmes de version.
L'unicité, les références à de «vraies» ressources, des minuteries et de nombreux autres types d'artefacts ne sont PAS candidats à la sérialisation.
Lisez ceci pour comprendre l'interface sérialisable et pourquoi nous devrions créer seulement quelques classes sérialisables. Nous devons également veiller à utiliser le mot clé transitoire si nous voulons supprimer quelques champs de la procédure de stockage.
Eh bien, ma réponse est que ce n'est pas pour une bonne raison. Et d'après vos commentaires, je constate que vous l'avez déjà appris. Les autres langues essayent avec plaisir de sérialiser tout ce qui ne saute pas dans une arborescence après avoir compté jusqu'à 10. Un objet doit par défaut être sérialisable.
Vous devez donc lire toutes les propriétés de votre classe tierce vous-même. Ou, si c'est une option pour vous: décompilez, mettez le maudit mot-clé ici et recompilez.
Bien que je sois d’accord avec les arguments avancés dans d’autres réponses, le problème réel est la désérialisation: si la définition de la classe change, le risque est réel que la désérialisation ne fonctionne pas. Ne jamais modifier les champs existants est un engagement assez important pour l'auteur d'une bibliothèque à prendre! Maintenir la compatibilité des API est déjà une corvée suffisante.
Certains éléments de Java ne peuvent tout simplement pasbe être sérialisés, car ils sont spécifiques à l'exécution. Des choses comme les flux, les threads, le runtime, .__, etc. et même certaines classes d'interface graphique (qui sont connectées au système d'exploitation sous-jacent) ne peuvent pas.
Une classe qui doit être conservée dans un fichier ou un autre support doit implémenter une interface sérialisable, de sorte que la machine virtuelle Java puisse autoriser la sérialisation de l'objet de la classe . Pourquoi la classe objet n'est pas sérialisée, aucune des classes ne doit implémenter l'interface Après tout, la JVM sérialise la classe uniquement lorsque j’utilise ObjectOutputStream , ce qui signifie que le contrôle est toujours entre mes mains pour permettre à la JVM de se sérialiser.
La raison pour laquelle la classe d'objets n'est pas sérialisable par défaut du fait que la version de la classe est le problème majeur. Par conséquent, chaque classe intéressée par la sérialisation doit être explicitement identifiée comme Serializable et fournir un numéro de version serialVersionUID.
Si serialVersionUID n'est pas fourni, nous obtenons des résultats inattendus lors de la désérialisation de l'objet. C'est pourquoi JVM lève InvalidClassException if serialVersionUID ne correspond pas. Par conséquent, chaque classe doit implémenter Serializable interface et fournir serialVersionUID pour s'assurer que la classe présentée aux deux extrémités est identique.