Was ist der Unterschied zwischen Serializable
und Externalizable
in Java?
Was ist der Unterschied zwischen Serializable
und Externalizable
in Java?
Um die anderen Antworten zu ergänzen java.io.Serializable
, erhalten Sie durch die Implementierung eine "automatische" Serialisierungsfunktion für Objekte Ihrer Klasse. Sie müssen keine andere Logik implementieren, es funktioniert einfach. Die Java-Laufzeit verwendet Reflection, um herauszufinden, wie Sie Ihre Objekte ein- und ausmarschieren können.
In früheren Versionen von Java war die Reflexion sehr langsam, und daher war das Serialisieren großer Objektdiagramme (z. B. in Client-Server-RMI-Anwendungen) ein kleines Leistungsproblem. Um diese Situation zu bewältigen, wurde die java.io.Externalizable
Schnittstelle bereitgestellt, die java.io.Serializable
mit benutzerdefinierten Mechanismen ausgestattet ist, um die Marshalling- und Unmarshalling-Funktionen auszuführen (Sie müssen readExternal
und writeExternal
Methoden für Ihre Klasse implementieren ). Dies gibt Ihnen die Möglichkeit, den Engpass bei der Reflexionsleistung zu umgehen.
In neueren Versionen von Java (sicherlich ab 1.3) ist die Reflexionsleistung erheblich besser als früher, und dies ist daher weitaus weniger problematisch. Ich vermute, es würde Ihnen schwer fallen, Externalizable
mit einer modernen JVM einen sinnvollen Nutzen daraus zu ziehen.
Außerdem ist der integrierte Java-Serialisierungsmechanismus nicht der einzige. Sie können Ersatz von Drittanbietern erhalten, z. B. die JBoss-Serialisierung, die erheblich schneller ist und als Ersatz für die Standardeinstellung dient.
Ein großer Nachteil Externalizable
ist, dass Sie diese Logik selbst beibehalten müssen. Wenn Sie ein Feld in Ihrer Klasse hinzufügen, entfernen oder ändern, müssen Sie Ihre writeExternal
/ readExternal
-Methoden ändern , um dies zu berücksichtigen.
Zusammenfassend Externalizable
ist ein Relikt der Java 1.1 Tage. Es ist wirklich nicht mehr nötig.
Externalizable
hilft dies sehr .Externalizable
viel besser zu mir passt, da ich keine Arrays mit leeren Leerzeichen oder Platzhalterobjekten ausgeben möchte und mit der expliziten Schnittstelle, die Sie für die Vererbung verwenden können, was mein synchronisiertes Sub bedeutet -Klasse kann leicht Sperren um den Anruf hinzufügenwriteExternal()
. Also ja, Externalizable ist immer noch sehr relevant, sicherlich für große oder komplexe Objekte.Die Serialisierung bietet Standardfunktionen zum Speichern und späteren Neuerstellen des Objekts. Es verwendet ein ausführliches Format, um das gesamte Diagramm der zu speichernden Objekte zu definieren. Nehmen wir beispielsweise an, Sie haben eine verknüpfte Liste und codieren wie unten beschrieben. Bei der Standard-Serialisierung werden alle verknüpften Objekte erkannt und serialisiert. In der Standard-Serialisierung wird das Objekt vollständig aus seinen gespeicherten Bits ohne Konstruktoraufrufe erstellt.
Wenn Sie jedoch eine eingeschränkte Serialisierung wünschen oder nicht möchten, dass ein Teil Ihres Objekts serialisiert wird, verwenden Sie Externalizable. Die Externalizable-Schnittstelle erweitert die Serializable-Schnittstelle und fügt zwei Methoden hinzu, writeExternal () und readExternal (). Diese werden während der Serialisierung oder Deserialisierung automatisch aufgerufen. Während der Arbeit mit Externalizable sollten wir uns daran erinnern, dass der Standardkonstruktor öffentlich sein sollte, da sonst der Code eine Ausnahme auslöst. Bitte folgen Sie dem folgenden Code:
Wenn Sie hier den Standardkonstruktor kommentieren, wird der Code die folgende Ausnahme auslösen:
Wir können beobachten, dass das Passwort vertrauliche Informationen sind, daher serialisiere ich es nicht in der Methode writeExternal (ObjectOutput oo) und setze nicht den Wert derselben in readExternal (ObjectInput oi). Das ist die Flexibilität, die Externalizable bietet.
Die Ausgabe des obigen Codes erfolgt wie folgt:
Wir können beobachten, dass wir den Wert von passWord nicht so einstellen, dass er null ist.
Das gleiche kann auch erreicht werden, indem das Passwortfeld als vorübergehend deklariert wird.
Ich hoffe es hilft. Ich entschuldige mich, wenn ich Fehler gemacht habe. Vielen Dank.
quelle
Hauptunterschiede zwischen
Serializable
undExternalizable
Serializable
ist eine Marker-Schnittstelle ohne Methoden.Externalizable
Schnittstelle enthält zwei Methoden:writeExternal()
undreadExternal()
.Serializable
Schnittstelle implementieren . Der vom Programmierer definierte Serialisierungsprozess wird für Klassen, die dieExternalizable
Schnittstelle implementieren, aktiviert.Externalizable
Benutzeroberfläche haben. Sie können verschiedene Versionen Ihres Objekts unterstützen. Wenn Sie implementierenExternalizable
, liegt es in Ihrer Verantwortung, diesuper
Klasse zu serialisierenSerializable
Verwendet Reflektion zum Konstruieren von Objekten und benötigt keinen arg-Konstruktor. AberExternalizable
verlangt Öffentlichkeit nicht argument Konstruktor.Weitere Informationen finden Sie im Blog von
Hitesh Garg
.quelle
Bei der Serialisierung werden bestimmte Standardverhalten verwendet, um das Objekt zu speichern und später neu zu erstellen. Sie können angeben, in welcher Reihenfolge oder wie mit Referenzen und komplexen Datenstrukturen umgegangen werden soll. Letztendlich kommt es jedoch darauf an, das Standardverhalten für jedes primitive Datenfeld zu verwenden.
Die Externalisierung wird in den seltenen Fällen verwendet, in denen Sie Ihr Objekt wirklich auf eine völlig andere Weise speichern und neu erstellen möchten, ohne die Standard-Serialisierungsmechanismen für Datenfelder zu verwenden. Stellen Sie sich zum Beispiel vor, Sie hätten Ihr eigenes einzigartiges Kodierungs- und Komprimierungsschema.
quelle
Die Objektserialisierung verwendet die Schnittstellen Serializable und Externalizable. Ein Java-Objekt ist nur serialisierbar. Wenn eine Klasse oder eine ihrer Oberklassen entweder die Schnittstelle java.io.Serializable oder ihre Unterschnittstelle java.io.Externalizable implementiert. Die meisten Java-Klassen sind serialisierbar .
NotSerializableException
:packageName.ClassName
«Um ein Klassenobjekt am Serialisierungsprozess teilzunehmen, muss die Klasse entweder eine serialisierbare oder eine externisierbare Schnittstelle implementieren.Serialisierbare Schnittstelle
Die Objektserialisierung erzeugt einen Stream mit Informationen zu den Java-Klassen für die Objekte, die gespeichert werden. Für serialisierbare Objekte werden ausreichende Informationen gespeichert, um diese Objekte wiederherzustellen, selbst wenn eine andere (aber kompatible) Version der Implementierung der Klasse vorhanden ist. Die serialisierbare Schnittstelle ist definiert, um Klassen zu identifizieren, die das serialisierbare Protokoll implementieren:
InvalidClassException
«Im Deserialisierungsprozess, wenn sich der Wert der lokalen Klasse serialVersionUID von der Klasse des entsprechenden Absenders unterscheidet. dann ist das in Konflikt alsjava.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
Externalisierbare Schnittstelle
Bei externisierbaren Objekten wird vom Container nur die Identität der Klasse des Objekts gespeichert. Die Klasse muss den Inhalt speichern und wiederherstellen. Die externisierbare Schnittstelle ist wie folgt definiert:
OptionalDataException
«Die Felder müssen in der gleichen Reihenfolge und Art sein, wie wir sie geschrieben haben. Wenn der Stream nicht übereinstimmt, wird eine OptionalDataException ausgelöst.Die Instanzfelder der Klasse, die geschrieben (verfügbar gemacht) wurden ,
ObjectOutput
um serialisiert zu werden.Beispiel « implementiert Serializable
Beispiel « implementiert Externalizable
Beispiel
@sehen
quelle
Die externisierbare Schnittstelle wurde nicht bereitgestellt, um die Leistung des Serialisierungsprozesses zu optimieren! aber um Mittel zur Implementierung Ihrer eigenen benutzerdefinierten Verarbeitung bereitzustellen und die vollständige Kontrolle über das Format und den Inhalt des Streams für ein Objekt und seine Supertypen zu bieten!
Beispiele hierfür sind die Implementierung von AMF-Remoting (ActionScript Message Format) zum Übertragen nativer Aktionsskriptobjekte über das Netzwerk.
quelle
https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
Die Standardserialisierung ist etwas ausführlich und setzt ein möglichst breites Verwendungsszenario des serialisierten Objekts voraus. Dementsprechend kommentiert das Standardformat (Serializable) den resultierenden Stream mit Informationen über die Klasse des serialisierten Objekts.
Durch die Externalisierung erhält der Produzent des Objektstroms die vollständige Kontrolle über die genauen Klassenmetadaten (falls vorhanden), die über die minimal erforderliche Identifizierung der Klasse (z. B. ihren Namen) hinausgehen. Dies ist in bestimmten Situationen eindeutig wünschenswert, z. B. in geschlossenen Umgebungen, in denen der Produzent des Objektstroms und sein Verbraucher (der das Objekt aus dem Stream reifiziert) übereinstimmen und zusätzliche Metadaten über die Klasse keinen Zweck erfüllen und die Leistung beeinträchtigen.
Zusätzlich (wie Uri betont) ermöglicht die Externalisierung auch die vollständige Kontrolle über die Codierung der Daten im Stream, die Java-Typen entsprechen. Für ein (erfundenes) Beispiel möchten Sie möglicherweise den Booleschen Wert true als 'Y' und false als 'N' aufzeichnen. Mit der Externalisierung können Sie dies tun.
quelle
Vergessen Sie bei der Prüfung von Optionen zur Leistungsverbesserung nicht die benutzerdefinierte Serialisierung. Sie können Java kostenlos das tun lassen, was es gut oder zumindest gut genug macht , und benutzerdefinierten Support für das bieten, was es schlecht macht. Dies ist normalerweise viel weniger Code als die vollständige Unterstützung von Externalizable.
quelle
Es gibt so viele Unterschiede zwischen Serializable und Externalizable, aber wenn wir den Unterschied zwischen benutzerdefiniertem Serializable (überschriebenes writeObject () & readObject ()) und Externalizable vergleichen, stellen wir fest, dass die benutzerdefinierte Implementierung eng mit der ObjectOutputStream-Klasse verbunden ist, wo wir uns wie im Fall Externalizable befinden Stellen Sie eine Implementierung von ObjectOutput bereit, die eine ObjectOutputStream-Klasse oder eine andere wie org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream sein kann
Im Falle einer externalisierbaren Schnittstelle
Ich habe Beispielcode hinzugefügt, um dies besser zu erklären. Bitte checken Sie den Objektfall von Externalizable ein / aus. Diese sind nicht direkt an eine Implementierung gebunden.
Wobei Outstream / Instream eng an Klassen gebunden sind. Wir können ObjectOutputStream / ObjectInputStream erweitern, aber es wird etwas schwierig zu bedienen sein.
quelle
Grundsätzlich
Serializable
handelt es sich um eine Markierungsschnittstelle, die impliziert, dass eine Klasse für die Serialisierung sicher ist und die JVM bestimmt, wie sie serialisiert wird.Externalizable
enthält 2 MethodenreadExternal
undwriteExternal
.Externalizable
Ermöglicht dem Implementierer zu entscheiden, wie ein Objekt serialisiert wird, wobeiSerializable
Objekte standardmäßig serialisiert werden.quelle
Einige Unterschiede:
Für die Serialisierung ist kein Standardkonstruktor dieser Klasse erforderlich, da Object, da JVM dasselbe mithilfe der Reflection-API erstellt. Im Falle einer Externalisierung ist ein Konstruktor ohne Argument erforderlich, da die Steuerung programmgesteuert ist und die deserialisierten Daten später über Setter dem Objekt zugewiesen werden.
Wenn der Benutzer bei der Serialisierung bestimmte zu überspringende Eigenschaften überspringen möchte, muss er diese Eigenschaften als vorübergehend markieren. Für die Externalisierung ist umgekehrt nichts erforderlich.
Wenn für eine Klasse Unterstützung für die Abwärtskompatibilität erwartet wird, wird empfohlen, Externalizable zu verwenden. Die Serialisierung unterstützt das Fortbestehen von defaultObject. Wenn die Objektstruktur beschädigt ist, treten beim Deserialisieren Probleme auf.
quelle