Kürzlich habe ich das Grundwissen von Java zusammengestellt, und die Informationen zur Java -Serialisierung und -Deserialisierung wurden im Detail aussortiert. Ich werde hier eine Notiz nehmen, in der Hoffnung, dass es auch Freunden helfen wird, die diesen Artikel lesen.
1. Das Konzept der Serialisierung und Deserialisierung
Der Prozess der Konvertierung eines Objekts in eine Sequenz von Bytes wird als Serialisierung eines Objekts bezeichnet.
Der Prozess der Wiederherstellung einer Sequenz von Bytes in ein Objekt wird als Deserialisierung eines Objekts bezeichnet.
Für die Serialisierung von Objekten gibt es zwei Hauptverwendungen:
1) Speichern Sie die Byte -Sequenz von Objekten dauerhaft auf der Festplatte, normalerweise in einer Datei;
2) Übertragen Sie die Byte -Sequenz von Objekten im Netzwerk.
In vielen Anwendungen müssen bestimmte Objekte serialisiert werden, damit sie den Speicherplatz verlassen und zur physischen Festplatte für Langzeitspeicher übergehen. Zum Beispiel ist das Sitzungsobjekt auf dem Webserver am häufigsten. Wenn 100.000 Benutzer gleichzeitig zugreifen, können 100.000 Sitzungsobjekte angezeigt werden, und der Speicher kann es möglicherweise nicht tragen. Daher serialisiert der Webcontainer zuerst einige Segierungen auf die Festplatte und wartet, bis er verwendet wird, und stellen dann die in der Festplatte gespeicherten Objekte auf dem Speicher wieder her.
Wenn zwei Prozesse remote kommunizieren, können sie verschiedene Arten von Daten aneinander senden. Unabhängig davon, welche Art von Daten ist, wird sie in Form einer binären Sequenz im Netzwerk übertragen. Der Absender muss dieses Java -Objekt in eine Abfolge von Bytes umwandeln, um im Netzwerk übertragen zu werden. Der Empfänger muss die Bytes in ein Java -Objekt wiederherstellen.
2. Serialisierungs -API in der JDK -Klassenbibliothek
java.io.objectoutputStream repräsentiert den Objektausgabestrom. Die Methode "WriteObject (Object OBJ) kann das vom Parameter angegebene OBJ -Objekt serialisieren und die erhaltene Byte -Sequenz in einen Zielausgangsstrom schreiben.
java.io.objectInputStream repräsentiert den Objekteingangsstrom. Die Methode ReadObject () liest Byte -Sequenzen aus einem Quelleingabestream, wird sie in ein Objekt deserialisiert und gibt sie zurück.
Nur Objekte von Klassen, die serialisierbare und externalisierbare Schnittstellen implementieren, können serialisiert werden. Die externalisierbare Schnittstelle erbt von der serialisierbaren Schnittstelle. Die Klassen, die die externalisierbare Schnittstelle implementieren, steuern das Serialisierungsverhalten vollständig, während Klassen, die nur die serialisierbare Schnittstelle implementieren, die Standard -Serialisierungsmethode übernehmen können.
Die Objektserialisierung enthält die folgenden Schritte:
1) Erstellen Sie einen Objektausgabestream, der einen anderen Typ des Zielausgabestreams wie den Dateiausgabestream einwickeln kann.
2) Schreiben Sie das Objekt über die WriteObject () -Methode des Objektausgabestroms.
Die Schritte zur Deserialisierung eines Objekts sind wie folgt:
1) Erstellen Sie einen Objekteingabestream, der einen anderen Quelleingabestream wie den Dateieingabestream einwickeln kann.
2) Lesen Sie das Objekt über die Methode readObject () des Objekteingabestreams.
Objektserialisierung und Abschlüsse Beispiele:
Definieren Sie eine Personklasse, um die serialisierbare Schnittstelle zu implementieren
1 Import Java.io.Serializable; 2 3 /** 4 * <p>ClassName: Person<p> 5 * <p>Description: Test object serialization and deserialization<p> 6 * @author xudp 7 * @version 1.0 V 8 * @createTime 2014-6-9 02:33:25 pm 9 */10 public class Person implements Serializable {11 12 /**13 * Serialization ID14 */15 private static final long serialversionuid = -5809782578272943999l; 16 private int alter; 17 private String -Name; 18 private String Sex; 19 20 public int getage () {21 return ay; 22} 23 24 public String getName () {25 Return -Name; 26} 27 28 öffentliche String GetSex () {29 Return; Alter; 34} 35 36 public void setName (String name) {37 this.name = name; 38} 39 40 public void setSex (String Sex) {41 this.sex = sex; 42} 43}Serialisiere und deserialisieren von Personenklassenobjekten
import Java.io.file; import Java.io.fileinputstream; Import Java.io.filenotFoundException; Import Java.io.FileOutputStream; Import Java.io.ioException; importieren Sie Java.io.o. TestObjserializeandDeSerialize <p> * <P> Beschreibung: Serialisierung und Deserialisierung von Testobjekten <P> * @Author XUDP * @VERSION 1.0 V * @CreateTime 2014-6-9 03:17:25 PM */Public testobjSerializeAndDeserialize {öffentliches statisches statisches VOID-AUSSCHLAGEN [] String. SerializePerson (); // serialisieren personenobjektperson p = DeserializePerson (); // Deserial Perrons Object System.out.println (messageFormat.format ("name = {0}, ay = {1}, sex = {2}", P.getname (), P.Getage (), P.Getsex ()); } / ** * methodName: serializePerson * Beschreibung: Serialize Person -Objekt * @author xUdp * @throws FileFoundException * @throws ioException * / private static void serializePerson () löscht FilenotFoundException, ioException {person = new Person (); Person.SetName ("GaCl"); Person.Setage (25); Person.SetSex ("männlich"); // ObjectOutputStream -Objektausgabe -Stream, speichern Sie das Personobjekt in der Person.txt -Datei auf der E -Festplatte und vervollständigen Sie den Serialisierungsvorgang des Personenobjekts. ObjectOutputStream oo = new ObjectOutputStream (neuer FileOutputStream (neue Datei ("e: /person.txt")); oo.writeObject (Person); System.out.println ("Person -Objekt -Serialisierung war erfolgreich!"); oo.close (); }/** * methodName: DeserializePerson * Beschreibung: DeserializePerson Object * @Author xUdp * @return * @throws Exception * @throws ioException */private statische Person DeserializePerson () löst Ausnahme aus, ioException {ObjectInputStream Ois = new ObjectinputStream (New FileStream (New File)). Person Person = (Person) ois.ReadObject (); System.out.println ("Personal -Objektdeserialisierung erfolgreich!"); Rückkehr Person; }}Die Code -Laufergebnisse sind wie folgt:
Nachdem die Person erfolgreich serialisiert wurde, wurde eine Person.txt -Datei auf E -Datenträger generiert, während die Deserialisierung der Person verwendet wird, um Person zu lesen.
3. Die Rolle von Serialversionuid
Seri alge ui d: bedeutet buchstäblich serialisierte Versionsnummer. Alle Klassen, die die serialisierbare Schnittstelle implementieren, haben eine statische Variable, die die serialisierte Versionskennung darstellt.
private statische letzte lange Serialversionuid
Wenn Serialversionuid nicht zur Klasse hinzugefügt wird, wird die folgende Warnung angezeigt.
Wenn Sie mit der Maus klicken, werden ein Dialogfeld angezeigt, das serialversionuid generiert wird, wie in der folgenden Abbildung gezeigt:
Es gibt zwei Möglichkeiten, serialversionuid zu generieren:
Die auf diese Weise erzeugte Serialversionuid ist beispielsweise 1L:
private statische endgültige lange Serialversionuid = 1L;
Die auf diese Weise generierte Serialversionuid wird basierend auf Klassennamen, Schnittstellennamen, Methode und Attribut usw. generiert, zum Beispiel:
Private statische endgültige lange Serialversionuid = 4603642343377807741L;
Nach dem Hinzufügen wird die Warnung nicht angezeigt, wie unten gezeigt:
Wie nutzen serialversionuid (serialisierte Versionsnummer), nachdem er darüber gesprochen hat? Verwenden wir das folgende Beispiel, um die Rolle von Serialversionuid zu veranschaulichen und den folgenden Code anzusehen:
1 Import Java.io.file; 2 Java.io.FileInputStream importieren; 3 Importieren Sie Java.io.filenotFoundException; 4 Import Java.io.FileOutputStream; 5 Import Java.io.ioException; 6 Import Java.io.objectinputStream; 7 importieren java.io.objectoutputStream; 8 Import Java.io.Serializable; 9 10 öffentliche Klasse TestSerialVersionUid {11 12 öffentliche statische void -Haupthaupt (String [] args) löst eine Ausnahme aus. * @Author XUDP22 * @Throws fileNotfoundException23 * @throws ioException24 */25 private statische void Serializecustomer () löscht FileNotfoundException aus, 26 IOException {27 Customer Customer = New Customer ("GaclaSoutputStream (" New ObjectoutputStream). FileOutputStream (30 neue Datei ("e: /customer.txt"))); 31 oo.writeObject (Kunde); 32 System.out.println ("Customer -Objekt -Serialisierung erfolgreich!"); XUDP40 * @return41 * @throws Exception42 * @throws ioException43 */44 private statische Kunden DeserializeCustomer () Ausnahme, IOException {45 ObjectInputStream OIS = new ObjectInputStream (New FileputStream (46 New Datei ("E: /customer.txt.))))))))))))))))))))))). Ois.ReadObject (); 48 System.out.println ("Deserialisierung der Kundenobjekte war erfolgreich! ");49 return customer;50 }51 }52 53 /**54 * <p>ClassName: Customer<p>55 * <p>Description: Customer implements the Serializable interface and can be serialized<p>56 * @author xudp57 * @version 1.0 V58 * @createTime 2014-6-9 04:20:1759 pm */60 class Customer implements Serializable {61 // no serialversionuid62 privater String -Name; 63 private int age; 64 65 öffentlicher Kunde (String -Name, int age) {66 this.name = name; 67 this.age = älter; 68} 69 70 / * 71 * @MethName toString72 * @Description Die toSstring () -Methode der Objektklasse 73 * @Description. String75 * @see java.lang.object#toString () 76 */77 @override78 public String toString () {79 return "name =" + name + ", ay" + älter; 80} 81}Auslaufergebnisse:
Sowohl die Serialisierung als auch die Deserialisierung waren erfolgreich.
Ändern wir die Kundenklasse und fügen Sie ein zusätzliches Sex -Attribut hinzu, wie folgt:
1 Klassenkunde implementiert serialisierbar {2 // Keine serialversionuid ist im Customer Class 3 Private String -Namen definiert; 4 privates Int -Alter; 5 6 // Neues Sex Attribut 7 Private String Sex; 8 9 öffentlicher Kunde (String -Name, int Alter) {10 this.name = name; 11 this.age = älter; 12} 13 14 öffentlicher Kunde (String -Name, int Alter, String Sex) {15 this.name = name; 16 this.age = Age; 17 This.sex = sex; XUDP24 * @Return String25 * @see java.lang.Object#toString () 26 */27 @override28 public String toString () {29 return "name =" + name + ", ay" + älter; 30} 31}Führen Sie dann den Dessequenzvorgang durch, und die folgenden Ausnahmeinformationen werden ausgelöst:
1 Ausnahme in Thread "Haupt" java.io.invalidclassexception: Kunde; 2 Lokale Klasse inkompatibel: 3 Stream ClassDesc Serialversionuid = -8817559979432325, 4 lokale Klasse Serialversionuid = -5182532647273106745
Dies bedeutet, dass die Klasse im Dateistrom und die Klasse im Klassenpfad, dh die modifizierte Klasse, unvereinbar ist. Sie stehen unter den Überlegungen zur Sicherheitsmechanismus. Das Programm wirft einen Fehler auf und weigert sich zum Laden. Was ist, wenn wir nach der Serialisierung wirklich ein Feld oder eine Methode hinzufügen müssen? Was soll ich tun? Das heißt, die Serialversionuid selbst anzugeben. Wenn der serialversionuid der Kundenklasse nicht angegeben ist, führt der Java -Compiler im Beispiel für testSerialVersionuid automatisch einen zusammenfassenden Algorithmus für diese Klasse durch, ähnlich wie der Fingerabdruck -Algorithmus. Solange die Datei einen weiteren Speicherplatz hat, ist die resultierende UID völlig unterschiedlich, was garantiert werden kann, dass diese Zahl unter so vielen Klassen eindeutig ist. Nachdem ein Feld hinzugefügt wurde, generiert der Compiler, da der Serialversionuid nicht angegeben ist, eine UID für uns, die natürlich nicht die gleichen ist wie die, die zuvor in der Datei gespeichert ist, sodass zwei Fehler mit inkonsistenten Serialisierungsversionsnummern vorhanden sind. Solange wir serialversionuid selbst angeben, können wir daher nach der Serialisierung ein Feld oder eine Methode hinzufügen, ohne die spätere Wiederherstellung zu beeinflussen. Das wiederhergestellte Objekt kann weiterhin verwendet werden, und es gibt auch mehr Methoden oder Attribute.
Ändern Sie als nächstes die Kundenklasse weiter und geben Sie einen serialversionuid an den Kunden an. Der geänderte Code lautet wie folgt:
Klasse Kunde implementiert serialisierbar { / ** * SerialversionUid (serialisierte Versionsnummer) in der Kundenklasse definiert * / privates statisches endgültiges long serialversionuid = -5182532647273106745L; privater Zeichenfolge Name; privates int Alter; // Neues Sex -Attribut // Privat String Sex; public customer (String name, int age) {this.name = name; this.age = Alter; } /*public customer (String -Name, int Alter, String Sex) {this.name = name; this.age = Alter; this.sex = sex; } *// * * @MethodName toString * @Description Die toString () -Methode der Objektklasse * @Author xUdp * @Return String * @see java.lang.Object#toString () */ @Override public String toSstring () {return "name =" }}Führen Sie den Serialisierungsvorgang erneut aus, serialisieren Sie das Kundenobjekt mit dem Speicher von Customer.txt-Datei auf der lokalen Festplatte, ändern Sie die Kundenklasse und fügen Sie das Sex-Attribut hinzu. Der geänderte Kundenklassencode lautet wie folgt:
Klasse Kunde implementiert serialisierbar { / ** * SerialversionUid (serialisierte Versionsnummer) in der Kundenklasse definiert * / privates statisches endgültiges long serialversionuid = -5182532647273106745L; privater Zeichenfolge Name; privates int Alter; // Neues Sex Attribut privater String Sex; public customer (String name, int age) {this.name = name; this.age = Alter; } public customer (String -Name, int Alter, String Sex) {this.name = name; this.age = Alter; this.sex = sex; } / * * @Methodname toString * @Description Die toString () -Methode der Objektklasse * @author xUdp * @return String * @see java.lang.object#toString () * / @Override public String toString () {return "name =" + name = ", AGEL =", " +", " +", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", " +", " +" Age; }}Führen Sie die Dessequence -Operation durch, und diesmal wird die Dessequenz erfolgreich sein, wie unten gezeigt:
4. Der Wert von Serialversionuid
Der Wert von Serialversionuid wird automatisch von der Java -Laufzeitumgebung erzeugt, basierend auf den internen Details der Klasse. Wenn der Quellcode der Klasse geändert und neu kompiliert wird, kann sich auch der Wert der Serialversionuid der neu generierten Klassendatei ändern.
Der Standardwert der Serialversionuid einer Klasse hängt vollständig von der Implementierung des Java -Compilers ab. Für dieselbe Klasse kann das Kompilieren mit verschiedenen Java -Compilern zu verschiedenen Serialversionuiden führen und auch gleich sein. Um die Unabhängigkeit und Sicherheit von Serialversionuid zu verbessern, wird dringend empfohlen, Serialversionuid in einer serialisierbaren Klasse zu definieren, wodurch ein klarer Wert zugewiesen wird.
Es gibt zwei Zwecke für die explizit definierende Serialversionuid:
1. In einigen Fällen wird erwartet, dass verschiedene Versionen der Klasse mit der Serialisierung kompatibel sind. Daher muss sichergestellt werden, dass verschiedene Versionen der Klasse dieselbe Serialversionuid aufweisen.
2. In einigen Fällen wird nicht erwartet, dass verschiedene Versionen der Klasse mit der Serialisierung kompatibel sind. Daher ist es erforderlich, sicherzustellen, dass verschiedene Versionen der Klasse unterschiedliche Serialversionuide aufweisen.
Danke fürs Lesen, ich hoffe, es kann Ihnen helfen. Vielen Dank für Ihre Unterstützung für diese Seite!