Pourquoi Java nécessite-t-il une interface sérialisable?

Nous travaillons énormément avec la sérialisation et le fait de devoir spécifier une balise sérialisable sur chaque object 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 ajoutez des implements Serializable – pourquoi n’ont-ils pas tout rendu 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 de la sérialisation automatique de cette forme fait de la classe une partie intégrante de l’API publique (ce qui explique pourquoi javadoc vous fournit les formes de classes persistantes ).

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 casse l’encapsulation.

La sérialisation peut également entraîner des problèmes de sécurité. En étant capable de sérialiser tout object auquel il fait référence, une classe peut accéder aux données auxquelles elle ne serait normalement pas capable (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 qui ne sont pas bien définies.

Rendre toutes les classes sérialisables exacerberait ces problèmes. Jetez un coup d’ œil à la deuxième édition de Java , en particulier à l’ article 74: Implémenter judicieusement Serializable .

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é.

Par exemple, dans Smalltalk (un langage créé dans les années 70), chaque object est sérialisable par défaut. Je ne sais pas pourquoi ce n’est pas le cas en Java, compte tenu du fait que la grande majorité des objects peuvent être sérialisés en toute sécurité et que quelques-uns d’entre eux ne le sont pas.

Marquer un object comme sérialisable (avec une interface) ne rend pas par magie cet object sérialisable, il était sérialisable tout du long , c’est juste que maintenant vous avez exprimé quelque chose que le système aurait pu trouver lui-même, donc je ne vois aucune raison la sérialisation est comme elle est maintenant.

Je pense que c’était une mauvaise décision prise par les concepteurs ou que la sérialisation était une reflection après coup, ou que la plate-forme n’était jamais prête à effectuer une sérialisation par défaut sur tous les objects de manière sûre et cohérente.

Tout n’est pas vraiment sérialisable. Prenez une connexion de prise réseau, par exemple. Vous pouvez sérialiser les données / l’état de votre object 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 objects 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, tout comme l’amitié en C ++, elle est désactivée par défaut, même si cela coûte un peu pour rendre les choses sérialisables.

La sérialisation ajoute des contraintes et des problèmes potentiels car la compatibilité de la structure n’est pas assurée. Il est bon que ce soit désactivé par défaut.

Je dois admettre que j’ai vu très peu de classes non sortingviales où la sérialisation standard fait ce que je veux. Surtout dans le cas de structures de données complexes. Ainsi, les efforts que vous consacreriez à la classe serializble réduisent le coût de l’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 de firebase database, 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 à gérer des instances de différentes versions d’une classe, ce que vous ne voudrez peut-être pas.

Sans doute, il aurait peut-être été préférable de tout rendre Serializable par défaut et de rendre les classes non sérialisables via une interface de mots-clés ou de marqueurs – mais ceux qui devraient utiliser cette option n’y penseraient probablement pas. Si tel est le cas, si vous avez besoin d’implémenter Serializable, vous serez averti par une exception.

Je pense que le but était de vous assurer, en tant que programmeur, que votre object soit sérialisé.

Apparemment, tout était sérialisable dans certaines conceptions préliminaires, mais en raison de la sécurité et de l’exactitude, la conception finale a fini comme nous le soaps tous.

Source: Pourquoi les classes doivent-elles implémenter Serializable pour pouvoir écrire dans un ObjectOutputStream? .

Ayant à déclarer explicitement que les instances d’une certaine classe sont sérialisables, le langage vous oblige à réfléchir si vous le permettez. Pour les objects de valeur simples, la sérialisation est sortingviale, mais dans les cas plus complexes, vous devez vraiment réfléchir.

En vous appuyant uniquement sur la prise en charge de la sérialisation standard de la machine virtuelle Java, vous vous exposez à toutes sortes de problèmes de versioning.

L’unicité, les références aux ressources «réelles», les timers et de nombreux autres types d’artefacts ne sont PAS des candidats pour la sérialisation.

Lisez ceci pour comprendre l’interface Serializable et pourquoi nous ne devrions faire que quelques classes Serializable et nous avons également pris 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/

Eh bien, ma réponse est que c’est pour rien. Et d’après vos commentaires, je peux voir que vous l’avez déjà appris. Les autres langages essayent heureusement de sérialiser tout ce qui ne saute pas sur un arbre après avoir compté jusqu’à 10. Un object doit être sérialisable par défaut.

Donc, vous devez essentiellement lire vous-même toutes les propriétés de votre classe tierce. Ou, si c’est une option pour vous: décomstackr, mettre le mot clé damn là et recomstackr.

Certaines choses dans Java ne peuvent tout simplement pas être sérialisées car elles sont spécifiques à l’exécution. Des éléments tels que les stream, les threads, le runtime, etc. et même certaines classes d’interface graphique (connectées au système d’exploitation sous-jacent) ne peuvent pas être sérialisés.

Bien que je sois d’accord avec les points soulevés dans d’autres réponses, le véritable problème concerne la désérialisation: si la définition de classe change, il existe un risque réel que la désérialisation ne fonctionne pas. Ne jamais modifier les champs existants est un engagement majeur pour l’auteur d’une bibliothèque! Maintenir la compatibilité API est une corvée suffisante.

Une classe devant être conservée dans un fichier ou un autre support doit implémenter une interface Serializable, afin que la machine virtuelle Java puisse autoriser la sérialisation de l’object de classe. Pourquoi la classe Object n’est pas sérialisée alors aucune des classes n’a besoin de mettre en œuvre l’interface, après que JVM ait sérialisé la classe uniquement lorsque j’utilise ObjectOutputStream, ce qui signifie que le contrôle est toujours dans mes mains pour permettre à la JVM de 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 classe est le problème majeur. Par conséquent, chaque classe intéressée par la sérialisation doit être marquée comme Serializable 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’object, c’est pourquoi JVM émet 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.