Nous travaillons beaucoup avec la sérialisation et devoir spécifier une balise Serializable sur chaque objet que nous utilisons est une sorte de fardeau. Surtout quand c'est 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 l'avez ajoutée implements Serializable
- pourquoi n'ont-ils pas tout rendu sérialisable et c'est tout?
Qu'est-ce que je rate?
java
serialization
Yoni Roit
la source
la source
Réponses:
La sérialisation est semée d'embûches. La prise en charge de la sérialisation automatique de ce formulaire fait des composants internes de classe une partie de l'API publique (c'est pourquoi javadoc vous donne les formes persistantes de classes ).
Pour une persistance à long terme, la classe doit être capable de décoder ce formulaire, ce qui limite les modifications que vous pouvez apporter à la conception de classe. Cela rompt l'encapsulation.
La sérialisation peut également entraîner des problèmes de sécurité. En étant capable de sérialiser tout objet auquel elle fait référence, une classe peut accéder aux données auxquelles elle ne serait normalement pas en mesure (en analysant les données d'octet résultantes).
Il y a d'autres problèmes, tels que la forme sérialisée des classes internes qui n'est pas bien définie.
Rendre toutes les classes sérialisables aggraverait ces problèmes. Consultez la deuxième édition effective de Java , en particulier l' article 74: Implémenter judicieusement sérialisable .
la source
Je pense que les utilisateurs de Java et de .Net se sont trompés cette fois-ci, il aurait été préférable de tout rendre sérialisable par défaut et de ne marquer que les classes qui ne peuvent pas être sérialisées en toute sécurité à la place.
Par exemple dans Smalltalk (un langage créé dans les années 70), chaque objet est sérialisable par défaut. Je n'ai aucune idée pourquoi ce n'est pas le cas en Java, étant donné que la grande majorité des objets sont sûrs à sérialiser et que quelques-uns ne le sont pas.
Marquer un objet comme sérialisable (avec une interface) ne le rend pas comme par magie 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, donc je ne vois aucune bonne raison pour la sérialisation étant la façon dont elle est maintenant.
Je pense que c'était soit une mauvaise décision prise par les concepteurs, soit que la sérialisation était une réflexion après coup, soit que la plate-forme n'était jamais prête à faire la sérialisation par défaut sur tous les objets de manière sûre et cohérente.
la source
Serializable
astuce n'est qu'une autre mauvaise décision qui a été prise il y a dix ou deux ans, et un ajout de plus à l'ennui lorsqu'il s'agit de pur java, comme certaines failles dans la collection et le traitement des chaînes dans la bibliothèque standard. Heureusement, il y a Kryo, mais c'est une dépendance et il faut d'abord la trouver. C'est ainsi que la sérialisation intégrée aurait dû être effectuée.Tout n'est pas vraiment sérialisable. Prenez une connexion de socket réseau, par exemple. Vous pourriez sérialiser les données / l'état de votre objet socket, mais l'essence d'une connexion active serait perdue.
la source
implements NotSerializable
:)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, comme l'amitié en C ++, il est désactivé par défaut, même si cela coûte un peu cher 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 consacreriez à la sérialisation de la classe éclipse correctement le coût d'ajout de l'interface.
la source
Pour certaines classes, en particulier celles qui représentent quelque chose de plus physique comme un fichier, un socket, un thread ou une connexion de base de données, cela n'a absolument aucun sens de sérialiser des instances. 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.
Sans doute, il aurait peut-être été préférable de tout rendre sérialisable par défaut et de rendre les classes non sérialisables via une interface de mot-clé ou de marqueur - mais alors, ceux qui devraient utiliser cette option n'y penseraient probablement pas. Dans l'état actuel des choses, si vous devez implémenter Serializable, une exception vous le dira.
la source
Je pense que le but était de vous assurer, en tant que programmeur, que votre objet peut être sérialisé.
la source
Apparemment, tout était sérialisable dans certaines conceptions préliminaires, mais en raison de problèmes de sécurité et d'exactitude, la conception finale a abouti, comme nous le savons tous.
Source: Pourquoi les classes doivent-elles implémenter Serializable pour être écrites dans un ObjectOutputStream? .
la source
Devoir déclarer explicitement que les instances d'une certaine classe sont sérialisables, le langage vous oblige à réfléchir si vous devez autoriser cela. 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 de sérialisation standard de la JVM, vous vous exposez à toutes sortes de problèmes de version désagréables.
L'unicité, les références à des ressources «réelles», des minuteries et de nombreux autres types d'artefacts ne sont PAS des candidats à la sérialisation.
la source
Lisez ceci pour comprendre l'interface sérialisable et pourquoi nous ne devrions créer que quelques classes sérialisables et nous prenons également soin de savoir où utiliser le mot clé transitoire au cas où nous voudrions supprimer quelques champs de la procédure de stockage.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
la source
Eh bien, ma réponse est que ce n'est pas pour une bonne raison. Et d'après vos commentaires, je peux voir que vous avez déjà appris cela. D'autres langages essaient volontiers de sérialiser tout ce qui ne saute pas dans une arborescence après avoir compté jusqu'à 10. Un objet doit être sérialisable par défaut.
Donc, ce que vous devez faire est de lire vous-même toutes les propriétés de votre classe tierce. Ou, si c'est une option pour vous: décompiler, mettre le putain de mot-clé là-bas et recompiler.
la source
Certaines choses en Java ne peuvent tout simplement pas être sérialisées car elles sont spécifiques à l'exécution. Des éléments comme les flux, les threads, le runtime, etc. et même certaines classes GUI (qui sont connectées au système d'exploitation sous-jacent) ne peuvent pas être sérialisés.
la source
Bien que je sois d'accord avec les points soulevés dans d'autres réponses ici, le vrai problème est avec la désérialisation: si la définition de classe change, il y a un risque 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! Le maintien de la compatibilité des API est déjà une corvée.
la source
Une classe qui doit être conservée dans un fichier ou un autre support doit implémenter une interface sérialisable, de sorte que JVM puisse autoriser la sérialisation de l'objet de classe. Pourquoi la classe Object n'est pas sérialisée alors aucune des classes n'a besoin d'implémenter l'interface, après tout JVM sérialise la classe uniquement lorsque j'utilise ObjectOutputStream, ce qui signifie que le contrôle est toujours entre mes mains pour laisser la JVM se sérialiser.
La raison pour laquelle la classe Object n'est pas sérialisable par défaut dans le 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 marquée comme sérialisable explicitement 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 si serialVersionUID ne correspond pas. Par conséquent, chaque classe doit implémenter une interface Serializable et fournir serialVersionUID pour s'assurer que la classe présentée aux deux extrémités est identique.
la source