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.
Verweise
-
http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100
-
http://stackoverflow.com/questions/419796/explicit-serialversionuid-considered-harmful
-
http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html?page=1
-
http://www.java-forums.org/new-java/8196-serialversionuid.html