Dieser Artikel beschreibt Objektserialisierung und Deserialisierung in Java. Teilen Sie es für alle für Ihre Referenz. Die Details sind wie folgt:
1. Einführung
Die Objekt -Serialisierung bezieht sich auf den Prozess der Konvertierung eines Objekts in eine Sequenz von Bytes, während Deserialisierung der Prozess der Wiederherstellung eines Objekts basierend auf einer Abfolge von Bytes ist.
Die Serialisierung wird in den folgenden Szenarien im Allgemeinen verwendet:
1. Speichern Sie das Objekt dauerhaft und speichern Sie die Byte -Sequenz des Objekts in der lokalen Datei.
2. Übergeben Sie Objekte im Netzwerk, indem Sie sie serialisieren;
3.. Übergeben Sie Objekte zwischen den Prozessen durch Serialisierung.
Die Klasse, zu der das Objekt gehört, muss die serialisierbare oder externealisierbare Schnittstelle implementieren, die serialisiert werden soll. Für Klassen, die eine serialisierbare Schnittstelle implementieren, übernimmt die Serialisierung und Deserialisierung die Standard -Serialisierungsmethode.
Java.io.objectoutputStream repräsentiert den Objektausgabestrom, und seine Methode WriteObject (Object OBJ) kann die Serialisierung des Objekts realisieren und die erhaltene Byte -Sequenz in den Zielausgangsstrom schreiben.
Java.io.objectinputStream repräsentiert den Objekteingangsstrom, und seine ReadObject () -Methode kann eine Sequenz von Bytes aus dem Quelleingabestream lesen, ihn in ein Objekt deserialisieren und zurückgeben.
2. verschiedene Möglichkeiten zur Serialisierung
Angenommen, eine Kundenklasse ist definiert, abhängig von der Serialisierungsmethode des Kunden kann es die folgenden Serialisierungsmethoden geben:
1. Implementieren Sie serialisierbare, undefinierte ReadObject- und WriteObject -Methoden
ObjectOutputStream verwendet JDK, um nicht-transientes Instanzvariablen des Kundenobjekts standardmäßig zu serialisieren.
ObjectInputStream deserialisiert nicht-transientes Instanzvariablen des Kundenobjekts mithilfe der JDK-Standardmethode.
2. Implementieren Sie serialisierbare und definieren
ObjectOutputStream ruft die Methode "WriteObject (ObjectOutputStream) der Kundenklasse auf, um nicht-transiente Instanzvariablen des Kundenobjekts zu serialisieren;
ObjectInputStream ruft die Methode ReadObject (ObjectInputStream in) der Kundenklasse auf, um nicht-transiente Instanzvariablen des Kundenobjekts zu deserialisieren.
3. Implementieren
ObjectOutputStream ruft die WriteExternale Methode der Kundenklasse auf, um nicht-transiente Instanzvariablen des Kundenobjekts zu serialisieren.
ObjectInputStream ist zuerst ein Objekt durch den parameterlosen Konstruktor der Kundenklasse und deserialisiert dann die nicht-transiente Instanzvariable des Kundenobjekts mithilfe der Readexternal-Methode.
A. Serialisierbare Schnittstelle
Die Klasse ermöglicht ihre Serialisierungsfunktionalität, indem die Schnittstelle java.io.serializable implementiert wird. Klassen, die diese Schnittstelle nicht implementieren, können keinen ihrer Zustände serialisieren oder deserialisieren. Alle Subtypen einer serialisierbaren Klasse sind selbst serialisierbar. Die Serialisierungsschnittstelle hat keine Methoden oder Felder und wird nur zur Identifizierung serialisierbarer Semantik verwendet.
Während des Deserialisierungsprozesses werden Felder der nichtserialisierten Klasse unter Verwendung des gemeinsamen oder geschützten parameterlosen Konstruktors der Klasse initialisiert. Die serialisierbare Unterklasse muss in der Lage sein, auf den parameterlosen Konstruktor zugreifen zu können. Felder, die serialisierbare Unterklassen sein können, werden aus dem Strom wiederhergestellt.
Wenn Sie eine Klassenansicht durchqueren, können Sie Objekte begegnen, die die serialisierbare Schnittstelle nicht unterstützen. In diesem Fall wird eine nicht serialisierbare Ausnahme geworfen und die nicht serialisierbare Klasse identifiziert.
1. genaue Signatur
Klassen, die eine spezielle Verarbeitung während der Serialisierung und Deserialisierung erfordern, müssen spezielle Methoden mit den folgenden genauen Signaturen implementieren:
Private void writeObject (java.io.objectoutputStream) löst IOException aus
private void readObject (java.io.objectinputStream in) löst IOException, classNotFoundException aus;
private void readObjectnodata () löst ObjectStreamException aus;
Die WriteObject -Methode ist für das Schreiben des Status eines Objekts einer bestimmten Klasse verantwortlich, damit die entsprechende ReadObject -Methode es wiederherstellen kann. Der Standardmechanismus zum Speichern der Felder des Objekts kann aufgerufen werden. DefaultWriteObject. Die Methode selbst muss keine Zustände der Superklasse oder Unterklasse einbeziehen. Der Zustand kann gespeichert werden, indem einzelne Felder mithilfe der WriteObject -Methode oder mit der von DataOutput unterstützten Methode für grundlegende Datentypen in den ObjektOutputStream geschrieben werden.
Die ReadObject -Methode ist für das Lesen und Wiederherstellen von Klassenfeldern aus dem Stream verantwortlich. Es kann in. Die DefauLtreadObject -Methode verwendet Informationen im Stream, um Felder von Objekten im Stream zuweisen, die über die entsprechenden angegebenen Felder im aktuellen Objekt gespeichert werden. Dies wird verwendet, um sich mit Situationen zu befassen, in denen neue Felder nach der Klassenentwicklung hinzugefügt werden müssen. Die Methode selbst muss keine Zustände der Superklasse oder Unterklasse einbeziehen. Der Zustand kann gespeichert werden, indem einzelne Felder mithilfe der WriteObject -Methode oder mit der von DataOutput unterstützten Methode für grundlegende Datentypen in den ObjektOutputStream geschrieben werden.
In dem Fall, in dem der Serialisierungsstrom die angegebene Klasse nicht als Superklasse auflistet, ist die ReadObjectNodata -Methode für die Initialisierung des Objektzustands einer bestimmten Klasse verantwortlich. Dies geschieht, wenn sich die vom Empfänger verwendete Deserialized Instance -Klasse vom Absender unterscheidet und die von der Empfängerversion erweiterte Klasse keine von der Absenderversion erweiterte Klasse ist. Es tritt auch auf, wenn der Serialisierungsstrom manipuliert wurde.
Wenn Sie Objekte in einen Stream schreiben, müssen Sie die serialisierbare Klasse des zu verwendenden alternativen Objekts angeben, und Sie sollten diese spezielle Methode mit einer genauen Signatur implementieren:
Any-Access-Modifier-Objekt writeReplace () löst ObjectStreamException aus;
Diese WriteRace -Methode wird durch die Serialisierung aufgerufen, vorausgesetzt, wenn diese Methode vorliegt und sie mit einer in der Klasse des serialisierten Objekts definierten Methode zugreifen kann. Daher kann die Methode einen privaten, geschützten und paketprivaten Zugriff haben. Der Zugriff auf die Unterklasse zu dieser Methode folgt den Java -Zugriffsregeln.
Beim Lesen einer Instanz einer Klasse aus einem Stream müssen Sie die genaue Signatur angeben, mit der die alternative Klasse diese spezielle Methode implementiert sollte.
Any-Access-Modifier-Objekt readResolve () löst ObjectStreamException aus;
Diese ReadResolve -Methode folgt den gleichen aufrufenden Regeln und Zugriffsregeln wie WriteReplace.
Wenn eine Klasse eine ReadResolve -Methode definiert, wird die ReadResolve -Methode am Ende der Deserialisierung aufgerufen, und das von der Methode zurückgegebene Objekt ist das Endergebnis der Deserialisierung.
2.Serialversionuid
Die Serialisierungslaufzeit verwendet eine Versionsnummer, die als Serialversionuid bezeichnet wird, um mit jeder serialisierbaren Klasse zu assoziieren, die während der Deserialisierung verwendet wird, um zu überprüfen, ob der Sender und der Empfänger des für das Objekt geladenen serialisierten Objekts. Wenn der Empfänger die Serialversionuid der Klasse des Objekts unterscheidet als die Versionsnummer des entsprechenden Absenders, führt die Deserialisierung zu einer InvalidClassexception. Eine serialisierbare Klasse kann explizit ihre eigene Serialversionuid erklären, indem er ein Feld namens "Serialversionuid" erklärt (dieses Feld muss ein statisches, letztes Feld sein):
Any-Access-Modifier statische endgültige lange Serialversionuid = 42L;
Wenn die serialisierbare Klasse nicht explizit Serialversionuid deklariert, berechnet die Serialisierungslaufzeit den Standard -Serialversionuid -Wert der Klasse, der auf verschiedenen Aspekten der Klasse basiert, wie in der "Java (TM) -Objekt -Serialisierungsspezifikation" beschrieben. Es wird jedoch dringend empfohlen, dass alle serialisierbaren Klassen ausdrücklich Serialversionuidwerte deklarieren, da die Berechnung der Standard -Serialversionuid hochempfindlich gegenüber den Details der Klassiker ist und je nach Compiler -Implementierung stark variieren kann kann resultieren. Um die Konsistenz zwischen serialversionuidischen Werten über verschiedene Java -Compiler hinweg sicherzustellen, muss die serialisierte Klasse einen expliziten serialversionuid -Wert deklarieren. Es wird auch dringend empfohlen, den privaten Modifikator zu verwenden, um die Erklärung serialversionuid nach möglich anzuzeigen, da solche Erklärungen nur zur direkten Deklaration der Klasse verwendet werden - das Feld Serialversionuid als ererbter Mitglied ist nicht nützlich. Array -Klassen können keine explizite serialversionuid deklarieren, daher haben sie immer den standardrechten berechneten Wert, aber die Array -Klassen stimmen nicht mit den serialversionuid -Wertanforderungen überein.
3.Externalisierbare Schnittstelle
Externalisierbar ist eine Erweiterung von Serailisierbar.
Rufen Sie die Methode der Klasse während der Serialisierung auf und deeserialisieren Sie die Readexternal -Methode.
Bei der Durchführung der Deserialisierung wird der parameterlose Konstruktor der Klasse zuerst aufgerufen, was sich von der Standarddeserialisierung unterscheidet.
Viertens Zusammenfassung
Wenn die Standard -Serialisierungsmethode angewendet wird, kann ihre Instanz serialisiert werden, solange eine Klasse die serialisierbare Schnittstelle implementiert. Im Allgemeinen sollten Klassen, die speziell für die Vererbung entwickelt wurden, versuchen, die serialisierbare Schnittstelle nicht zu implementieren, da die serialisierbare Schnittstelle, sobald die übergeordnete Klasse implementiert, serialisierbar sind.
Die Mängel der Standard -Serialisierungsmethode:
1. Es ist nicht sicher, sensible Daten direkt zu serialisieren, die für die Offenlegung des Objekts nicht geeignet sind.
2. Es wird nicht überprüft, ob die Mitgliedsvariablen des Objekts die richtigen Einschränkungen erfüllen, und die Daten manipuliert werden und einen abnormalen Betrieb verursachen.
3. Eine rekursive Durchführung des Objektdiagramms ist erforderlich.
V.
Durch die Implementierung des privaten Typs writeObject () und readObject () der serialisierbaren Schnittstelle oder zur Implementierung der externalisierbaren Schnittstelle, der Implementierung der Methoden writeExternal () und ReadExternal () und der Bereitstellung eines parameterlosen Konstruktors des öffentlichen Typs, um den Serialisierungsprozess zu steuern, IT IT IT IT IT IT-Vorgang zu steuern kann die Mängel der Standard -Serialisierungsmethode effektiv vermeiden.
Es ist zu hoffen, dass dieser Artikel für Java -Programmdesign aller hilfreich ist.