Quelle est la différence entre Serializable
et Externalizable
en Java?
Quelle est la différence entre Serializable
et Externalizable
en Java?
Pour ajouter aux autres réponses, en implémentant java.io.Serializable
, vous obtenez une capacité de sérialisation "automatique" pour les objets de votre classe. Pas besoin d'implémenter une autre logique, cela ne fera que fonctionner. Le runtime Java utilisera la réflexion pour comprendre comment marshaler et démarsaler vos objets.
Dans la version antérieure de Java, la réflexion était très lente, et donc la sérialisation de graphiques d'objets volumineux (par exemple dans les applications RMI client-serveur) était un peu un problème de performances. Pour gérer cette situation, l' java.io.Externalizable
interface a été fournie, qui est similaire java.io.Serializable
mais avec des mécanismes personnalisés pour effectuer les fonctions de marshaling et de démarshalling (vous devez implémenter readExternal
etwriteExternal
méthodes sur votre classe). Cela vous donne les moyens de contourner le goulot d'étranglement des performances de réflexion.
Dans les versions récentes de Java (à partir de la version 1.3, certainement), les performances de réflexion sont bien meilleures qu'elles ne l'étaient auparavant, et c'est donc beaucoup moins un problème. Je soupçonne que vous auriez du mal à tirer un avantage significatif d' Externalizable
une JVM moderne.
De plus, le mécanisme de sérialisation Java intégré n'est pas le seul, vous pouvez obtenir des remplacements tiers, tels que JBoss Serialization, qui est considérablement plus rapide et constitue un remplacement direct par défaut.
Un gros inconvénient Externalizable
est que vous devez maintenir cette logique vous-même - si vous ajoutez, supprimez ou modifiez un champ dans votre classe, vous devez changer vos méthodes writeExternal
/ readExternal
pour en tenir compte.
En résumé, Externalizable
est une relique des jours Java 1.1. Il n'y en a vraiment plus besoin.
Externalizable
aide beaucoup .Externalizable
me convient beaucoup mieux, car je ne veux pas générer de tableaux avec des espaces vides ou des objets d'espace réservé, ainsi qu'avec l'interface explicite, vous pouvez gérer l'héritage, ce qui signifie que mon sous synchronisé -class peut facilement ajouter un verrouillage autour de l'appelwriteExternal()
. Donc oui, l'externalisable est toujours très pertinent, certainement pour les objets grands ou complexes.La sérialisation fournit des fonctionnalités par défaut pour stocker et recréer ultérieurement l'objet. Il utilise un format détaillé pour définir le graphique entier des objets à stocker, par exemple, supposons que vous ayez une liste liée et que vous codiez comme ci-dessous, puis la sérialisation par défaut découvrira tous les objets liés et sérialisera. Dans la sérialisation par défaut, l'objet est entièrement construit à partir de ses bits stockés, sans appel de constructeur.
Mais si vous voulez une sérialisation restreinte ou si vous ne voulez pas qu'une partie de votre objet soit sérialisée, utilisez Externalizable. L'interface Externalizable étend l'interface Serializable et ajoute deux méthodes, writeExternal () et readExternal (). Ceux-ci sont automatiquement appelés lors de la sérialisation ou de la désérialisation. En travaillant avec Externalizable, nous devons nous rappeler que le constructeur par défaut doit être public, sinon le code lèvera une exception. Veuillez suivre le code ci-dessous:
Ici, si vous commentez le constructeur par défaut, le code lèvera l'exception ci-dessous:
Nous pouvons observer que le mot de passe étant une information sensible, je ne le sérialise donc pas dans la méthode writeExternal (ObjectOutput oo) et ne fixe pas la valeur de celui-ci dans readExternal (ObjectInput oi). C'est la flexibilité offerte par Externalizable.
La sortie du code ci-dessus est comme ci-dessous:
Nous pouvons observer que nous ne définissons pas la valeur de passWord, il est donc nul.
La même chose peut également être obtenue en déclarant le champ de mot de passe comme transitoire.
J'espère que ça aide. Je m'excuse si j'ai fait des erreurs. Merci.
la source
Différences clés entre
Serializable
etExternalizable
Serializable
est une interface de marqueur sans aucune méthode.Externalizable
L'interface contient deux méthodes:writeExternal()
etreadExternal()
.Serializable
interface. Le processus de sérialisation défini par le programmeur sera lancé pour les classes implémentant l'Externalizable
interface.Externalizable
interface. Vous pouvez prendre en charge différentes versions de votre objet. Si vous implémentezExternalizable
, il est de votre responsabilité de sérialisersuper
classeSerializable
utilise la réflexion pour construire l'objet et ne nécessite pas de constructeur arg. MaisExternalizable
exige un constructeur public sans argument.Consultez le blog de
Hitesh Garg
pour plus de détails.la source
La sérialisation utilise certains comportements par défaut pour stocker et recréer ultérieurement l'objet. Vous pouvez spécifier dans quel ordre ou comment gérer les références et les structures de données complexes, mais finalement cela revient à utiliser le comportement par défaut pour chaque champ de données primitif.
L'externalisation est utilisée dans les rares cas où vous souhaitez vraiment stocker et reconstruire votre objet d'une manière complètement différente et sans utiliser les mécanismes de sérialisation par défaut pour les champs de données. Par exemple, imaginez que vous disposiez de votre propre schéma d'encodage et de compression.
la source
La sérialisation d'objets utilise les interfaces sérialisables et externalisables. Un objet Java est uniquement sérialisable. si une classe ou l'une de ses superclasses implémente soit l'interface java.io.Serializable, soit sa sous-interface, java.io.Externalizable. La plupart des classes java sont sérialisables .
NotSerializableException
:packageName.ClassName
«Pour participer à un objet de classe dans le processus de sérialisation, la classe doit implémenter une interface sérialisable ou externalisable.Interface sérialisable
La sérialisation des objets produit un flux contenant des informations sur les classes Java pour les objets qui sont enregistrés. Pour les objets sérialisables, des informations suffisantes sont conservées pour restaurer ces objets même si une version différente (mais compatible) de l'implémentation de la classe est présente. L'interface sérialisable est définie pour identifier les classes qui implémentent le protocole sérialisable:
InvalidClassException
«Dans le processus de désérialisation, si la valeur de la classe serialVersionUID locale est différente de la classe de l'expéditeur correspondant. alors le résultat est en conflit commejava.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
Interface externalisable
Pour les objets externalisables, seule l'identité de la classe de l'objet est enregistrée par le conteneur; la classe doit sauvegarder et restaurer le contenu. L'interface externalisable est définie comme suit:
OptionalDataException
«Les champs doivent être dans le même ordre et type que nous les avons écrits. S'il y a une incompatibilité de type dans le flux, il lance OptionalDataException.Les champs d'instance de la classe qui ont écrit (exposés) pour
ObjectOutput
être sérialisés.Exemple « implémente Serializable
Exemple « implémente Externalizable
Exemple
@voir
la source
L'interface externalisable n'a pas été réellement fournie pour optimiser les performances du processus de sérialisation! mais pour fournir des moyens d'implémenter votre propre traitement personnalisé et offrir un contrôle complet sur le format et le contenu du flux pour un objet et ses super types!
La mise en œuvre d'AMF (ActionScript Message Format) à distance pour transférer des objets de script d'action natifs sur le réseau en est un exemple.
la source
https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
La sérialisation par défaut est quelque peu verbeuse et suppose le scénario d'utilisation le plus large possible de l'objet sérialisé, et en conséquence le format par défaut (sérialisable) annote le flux résultant avec des informations sur la classe de l'objet sérialisé.
L'externalisation donne au producteur du flux d'objets un contrôle complet sur les métadonnées de classe précises (le cas échéant) au-delà de l'identification minimale requise de la classe (par exemple, son nom). Cela est clairement souhaitable dans certaines situations, telles que les environnements fermés, où le producteur du flux d'objet et son consommateur (qui réifie l'objet du flux) sont mis en correspondance, et des métadonnées supplémentaires sur la classe ne servent à rien et dégradent les performances.
De plus (comme le souligne Uri), l'externalisation permet également un contrôle complet du codage des données dans le flux correspondant aux types Java. Pour un exemple (artificiel), vous souhaiterez peut-être enregistrer booléen vrai comme «Y» et faux comme «N». L'externalisation vous permet de le faire.
la source
Lorsque vous envisagez des options pour améliorer les performances, n'oubliez pas la sérialisation personnalisée. Vous pouvez laisser Java faire ce qu'il fait bien, ou du moins assez bien, gratuitement , et fournir un support personnalisé pour ce qu'il fait mal. Il s'agit généralement de beaucoup moins de code que la prise en charge externe complète.
la source
Il y a tellement de différences entre Serializable et Externalizable, mais lorsque nous comparons la différence entre Serializable personnalisé (écrasé writeObject () & readObject ()) et Externalizable, nous constatons que l'implémentation personnalisée est étroitement liée à la classe ObjectOutputStream où, comme dans le cas externalisable, nous-mêmes fournir une implémentation d'ObjectOutput qui peut être une classe ObjectOutputStream ou une autre comme org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream
En cas d'interface externalisable
J'ai ajouté un exemple de code pour mieux expliquer. veuillez archiver / retirer le boîtier d'objet d'Externalisable. Ceux-ci ne sont directement liés à aucune implémentation.
Là où Outstream / Instream sont étroitement liés aux classes. Nous pouvons étendre ObjectOutputStream / ObjectInputStream mais ce sera un peu difficile à utiliser.
la source
Fondamentalement,
Serializable
c'est une interface de marqueur qui implique qu'une classe est sûre pour la sérialisation et la JVM détermine comment elle est sérialisée.Externalizable
contient 2 méthodes,readExternal
etwriteExternal
.Externalizable
permet à l'implémenteur de décider comment un objet est sérialisé, où commeSerializable
sérialise les objets par défaut.la source
Quelques différences:
Pour la sérialisation, il n'y a pas besoin de constructeur par défaut de cette classe car Object car JVM le construit à l'aide de Reflection API. En cas d'externalisation, un constructeur sans arg est nécessaire, car le contrôle est en main du programme et plus tard, affectez les données désérialisées à l'objet via des setters.
Dans la sérialisation, si l'utilisateur souhaite ignorer certaines propriétés à sérialiser, il doit marquer ces propriétés comme transitoires, l'inverse n'est pas requis pour l'externalisation.
Lorsqu'une prise en charge de la compatibilité descendante est attendue pour n'importe quelle classe, il est recommandé d'utiliser Externalizable. La sérialisation prend en charge la persistance de defaultObject et si la structure de l'objet est brisée, cela entraînera un problème lors de la désérialisation.
la source