Pourquoi Java a besoin d'une interface sérialisable?
nous travaillons lourdement avec la sérialisation et devoir spécifier l'étiquette sérialisable sur chaque objet que nous utilisons est une sorte de fardeau. Surtout quand il s'agit d'un cours d'une tierce partie qu'on ne peut pas vraiment changer.
la question Est: puisque Serializable est une interface vide et Java fournit une serialization robuste une fois que vous ajoutez implements Serializable
- pourquoi n'ont-ils pas fait tout serialisable et c'est tout?
Qu'est-ce que je rate?
13 réponses
est semée d'embûches. Le support de sérialisation automatique de cette forme rend la classe internals partie de L'API publique (c'est pourquoi javadoc vous donne les formes persistantes de classes ).
pour la persistance à long terme, la classe doit pouvoir décoder cette forme, ce qui limite les changements que vous pouvez apporter à la conception de la classe. Cela brise l'encapsulation.
La sérialisationpeut aussi entraîner des problèmes de sécurité. En étant capable de sérialiser n'importe quel objet auquel il a une référence, une classe peut accéder aux données qu'elle ne pourrait normalement pas (en analysant les données de byte résultantes).
il y a d'autres questions, telles que la forme sérialisée des classes intérieures n'étant pas bien définie.
rendre toutes les classes sérialisables exacerberait ces problèmes. Vérifier Java Effective Deuxième Édition , en particulier article 74: mettre en œuvre sérialisable judicieusement .
je pense que les gens de Java et de .Net se sont trompés cette fois-ci, auraient mieux fait de rendre tout sérialisable par défaut et n'ont besoin que de marquer 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, considérant le fait que la grande majorité des objets sont sûrs à sérialiser et seulement quelques-uns d'entre eux Je ne le suis pas.
marquer un objet comme sérialisable (avec une interface) ne rend pas magiquement cet objet sérialisable, il était sérialisable tout au long de , c'est juste que maintenant vous avez exprimé quelque chose que le système aurait pu trouver tout seul, donc je ne vois pas de bonne raison pour la sérialisation étant la façon dont il est maintenant.
je pense que c'était soit une mauvaise décision prise par les concepteurs ou la sérialisation était une pensée après coup, ou la plate-forme a été jamais prêt à faire la sérialisation par défaut sur tous les objets de façon sûre et cohérente.
tout n'est pas vraiment sérialisable. Prenez une connexion réseau socket, par exemple. Vous pourriez sérialiser les données / l'état 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 serialisables. La sérialisation est un mécanisme très dangereux, surtout dans son implémentation par défaut. Par conséquent, comme friendship en C++, il est désactivé par défaut, même si cela coûte un peu pour rendre les choses sérialisables.
Sérialisation ajoute des contraintes et des problèmes potentiels car la structure de la compatibilité n'est pas assurée. Il est bon que c'est 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. Donc, l'effort que vous dépenseriez pour rendre la classe serializble correctement éclipse 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, une Socket, un Thread, ou une connexion DB, cela n'a absolument aucun sens de sérialiser des instances. Pour beaucoup d'autres, la sérialisation peut être problématique parce qu'elle détruit les contraintes d'unicité ou simplement vous oblige à traiter des instances de différentes versions d'une classe, ce que vous ne voulez peut-être pas.
sans doute, il aurait été préférable de rendre tout sérialisable par défaut et rendre les classes non-sérialisables par l'intermédiaire d'une interface de mots clés ou de marqueurs - mais alors, ceux qui devraient utiliser cette option n'y penseraient probablement pas. La façon dont il est, si vous avez besoin d'implémenter Serialisable, vous sera dit par une Exception.
je pense que le but était de vous assurer, en tant que programmeur, que votre objet soit sérialisé.
apparemment, tout était sérialisable dans certains dessins préliminaires, mais à cause de la sécurité et de l'exactitude concerne la conception finale a fini comme nous le savons tous.
devoir énoncer explicitement que les instances d'une certaine classe sont sérialisables la langue vous force à réfléchir si vous autorisez 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 comptant simplement sur le support standard de sérialisation de la JVM, vous vous exposez à toutes sortes de problèmes de versioning désagréables.
unicité, références à "réel" les ressources, les minuteries et beaucoup d'autres types d'artefacts ne sont pas des candidats pour la sérialisation.
lisez ceci pour comprendre L'Interface sérialisable et pourquoi nous devrions faire seulement quelques classes Serialisable et aussi nous shopuld prendre soin où utiliser le mot-clé transitoire dans le cas où nous voulons supprimer quelques champs de la procédure de stockage.
eh Bien, ma réponse est que ce n'est pour aucune bonne raison. Et d'après vos commentaires, je vois que vous l'avez déjà appris. D'autres langues essayent volontiers de sérialiser tout ce qui ne saute pas sur un arbre après avoir compté jusqu'à 10. Un objet doit être sérialisable par défaut.
donc, ce que vous devez essentiellement faire est de lire toutes les propriétés de votre classe de tiers vous-même. Ou, si c'est une option pour vous: decompile, mettez le mot-clé damn là, et recompile.
il y a des choses en Java qui ne peuvent pas être sérialisés parce qu'ils sont spécifiques à l'exécution. Des choses comme les flux, les fils, l'exécution, etc. et même certaines classes GUI (qui sont connectés au système d'exploitation sous-jacent) ne peuvent pas être sérialisé.
bien que je sois d'accord avec les points soulevés dans d'autres réponses, le vrai problème est la desérialisation: si la définition de la classe change, il y a un risque réel que la desérialisation ne fonctionne pas. Ne jamais modifier des champs existants est un engagement assez important pour l'auteur d'une bibliothèque à faire! Maintenir la compatibilité avec L'API est déjà une corvée.
une classe qui doit être maintenue sur un fichier ou un autre support doit implémenter une interface sérialisable, de sorte que JVM puisse permettre à l'objet de classe d'être sérialisé. Pourquoi la classe objet 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 seulement quand j'utilise ObjectOutputStream ce qui signifie que le contrôle est toujours dans mes mains pour laisser la JVM à sérialiser.
La raison pour laquelle la classe d'Objet n'est pas serialisable par défaut dans le fait que la version de classe est le problème principal. Par conséquent, chaque classe qui est intéressée par la sérialisation doit être marquée explicitement comme sérialisable et fournir un numéro de version serialVersionUID.
Si serialVersionUID n'est pas fourni alors nous obtenons des résultats inattendus tout en deserialzing l'objet, c'est pourquoi JVM jette InvalidClassException si serialVersionUID ne correspond pas. Par conséquent, chaque classe doit mettre en œuvre Serialisable interface et fournir serialVersionUID pour s'assurer que la classe présentée aux deux extrémités est identique.