Verstehe die serialVersionUID

Verstehen Sie die serialVersionUID

Wenn Sie jemals die Schnittstelle vonSerializableimplementiert haben, muss diese Warnmeldung angezeigt werden

The serializable class xxx does not declare a static final serialVersionUID field of type long

Also ... was ist serialVersionUID?

Die serialVersionUID wird als Versionskontrolle in einer Serializable-Klasse verwendet. Wenn Sie eine serialVersionUID nicht explizit deklarieren, erledigt JVM dies automatisch für Sie, basierend auf verschiedenen Aspekten Ihrer serialisierbaren Klasse, wie inJava™ Object Serialization Specification beschrieben.

1. SerialVersionUID-Beispiel

Die obige Anweisung ist am Anfang etwas schwer zu verstehen (zumindest ich). Lassen Sie uns ein Beispiel beginnen, um zu verstehen, wie die Serializable-Klasse SerialVersionUID verwendet, um die Versionskontrolle zu implementieren.

1.1 Address.java

Eine serialisierbare Klasse mit einer serialVersionUID von 1L.

import java.io.Serializable;

public class Address implements Serializable{

       private static final long serialVersionUID = 1L;

       String street;
       String country;

       public void setStreet(String street){
           this.street = street;
       }

       public void setCountry(String country){
           this.country = country;
       }

       public String getStreet(){
           return this.street;
       }

       public String getCountry(){
           return this.country;
       }

       @Override
       public String toString() {
           return new StringBuffer(" Street : ")
           .append(this.street)
           .append(" Country : ")
           .append(this.country).toString();
       }
}

1.2 WriteObject.java

Eine einfache Klasse zum Schreiben / Serialisieren des Adressobjekts in eine Datei - "c: \ address.ser".

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class WriteObject{

    public static void main (String args[]) {

       Address address = new Address();
       address.setStreet("wall street");
       address.setCountry("united states");

       try{

        FileOutputStream fout = new FileOutputStream("c:\\address.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fout);
        oos.writeObject(address);
        oos.close();
        System.out.println("Done");

       }catch(Exception ex){
           ex.printStackTrace();
       }
    }
}

1.3 ReadObject.java

Eine einfache Klasse zum Lesen / Deserialisieren des Adressobjekts aus der Datei "c: \ address.ser".

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ReadObject{

   public static void main (String args[]) {

       Address address;

       try{

           FileInputStream fin = new FileInputStream("c:\\address.ser");
           ObjectInputStream ois = new ObjectInputStream(fin);
           address = (Address) ois.readObject();
           ois.close();

           System.out.println(address);

       }catch(Exception ex){
           ex.printStackTrace();
       }
   }
}

2. Testen

Lassen Sie uns einige Tests durchführen, um die Verwendung von serialVersionUID zu demonstrieren.

2.1 Same serialVersionUID

Dieselbe serialVersionUID, es gibt kein Problem während des Deserialisierungsprozesses

javac Address.java
javac WriteObject.java
javac ReadObject.java
java WriteObject
java ReadObject
Street : wall street Country : united states

2.2 Different serialVersionUID

In Address.javachange the serialVersionUID to 2L (es war 1L) und kompilieren Sie es erneut.

javac Address.java
java ReadObject
java.io.InvalidClassException: Address; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
        ...
        at ReadObject.main(ReadObject.java:14)

Die "InvalidClassException" werden erhöht, da Sie eine Serialisierungsklasse mitserialVersionUID “1L” schreiben, aber versuchen, sie mit der aktualisierten SerialisierungsklasseserialVersionUID “2L” wieder abzurufen.

Die serialVersionUID muss während des Serialisierungs- und Deserialisierungsprozesses übereinstimmen.

When should update your serialVersionUID?
Wenn Ihre Serialisierungsklasse mit einigen inkompatiblen Java-Typänderungen an einer serialisierbaren Klasse aktualisiert wird, müssen Sie Ihre serialVersionUID aktualisieren.

Ausführliche Informationen zu den Änderungen des kompatiblen und inkompatiblen Java-Typs an einer serialisierbaren Klasse finden Sie inJava Object Serialization Specification.

3. Was ist mit der standardmäßigen serialVersionUID falsch?

Wenn keine serialVersionUID deklariert ist, verwendet JVM einen eigenen Algorithmus, um eine Standard-SerialVersionUID zu generieren. Sie können den Algorithmushere überprüfen.

The default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation und führen zu unerwarteten InvalidClassExceptions während des Deserialisierungsprozesses.

3.1 Client / Server environment

- Der Client verwendet die JVM von SUN unter Windows.
- Der Server verwendet JRockit unter Linux.

Der Client sendet eine serialisierbare Klasse mit der standardmäßig generierten serialVersionUID (z. B. 123L) über Socket an den Server. Der Server generiert möglicherweise während des Deserialisierungsprozesses eine andere serialVersionUID (z. B. 124L) und löst unerwartete InvalidClassExceptions aus.

3.2 File / Database environment

- App Nr. 1 verwendet die JVM von SUN unter Windows.
- App Nr. 2 verwendet JRockit unter Linux.

Durch die Serialisierung konnte in einer Datei oder Datenbank gespeichert werden. App # 1 speichert standardmäßig eine serialisierbare Klasse in der Datenbank, die serialVersionUID (z. B. 123L) generiert, während App # 2 während des Deserialisierungsprozesses möglicherweise eine andere serialVersionUID (z. B. 124L) generiert und unerwartete InvalidClassExceptions auslöst.

Sie können hier nachList of the JVM implementation suchen.

4. So generieren Sie serialVersionUID

Sie können JDK "serialver" oder Eclipse IDE verwenden, um die serialVersionUIDsee detail automatisch zu generieren.

Fazit

SUN wird Entwicklern dringend empfohlen, die serialVersionUID zu deklarieren, um das oben aufgeführte unterschiedliche JVM-Problem zu vermeiden. Ich empfehle jedoch, dass Sie verstehen, was Serialisierung ist, wie serialVersionUID die Versionskontrolle implementiert und warum Ihre Klasse Serialisierung verwenden muss. Das Verständnis des serialVersionUID-Konzepts ist besser als jede Empfehlung mit verbundenen Augen.