SerialVersionUID in Java
Dieses Tutorial demonstriert die Verwendung von SerialVersionUID
in Java.
SerialVersionUID
in Java
Die SerialVersionUID
wird bei der Serialisierung verwendet. Die Serialisierung ist ein Prozess, bei dem wir ein Objekt in einen Bytestrom konvertieren, um die Daten zu speichern und irgendwohin zu senden, und die Deserialisierung ist der umgekehrte Prozess.
Während des Serialisierungsprozesses ordnet die Java-Laufzeit jeder Serializable
-Klasse eine Versionsnummer zu; diese Nummer heißt SerialVersionUID
.
Mit der SerialVersionUID
wird verifiziert, dass Sender und Empfänger der serialisierten Daten die Klassen für diese Daten geladen haben und bezüglich der Serialisierung kompatibel sind.
Wenn zum Beispiel ein Empfänger eine Klasse für das Objekt mit einer anderen SerialVersionUID
geladen hat als die Klasse des entsprechenden Senders, wirft er die InvalidClassException
.
Wir können unsere eigene SerialVersionUID
für die Serializable
-Klasse deklarieren. Die SerialVersionUID
wird als Typ Static Final
und Long
deklariert.
Siehe Syntax:
private static final long serialVersionUID = 10L;
Versuchen wir ein Beispiel, das die Serialisierung und Deserialisierung mit der SerialVersionUID
implementiert. Siehe Beispiel:
package delftstack;
import java.io.*;
import java.util.logging.Logger;
public class Example implements java.io.Serializable {
// The Default serial version uid
private static final long serialVersionUID = 4L;
// random name
private static final String File_Name = "ExampleClassBytes.ser";
private static final Logger logger_File = Logger.getLogger("");
// Few data fields Which will be able to serialize
private static String Static_Variable;
private int Integer_Variable;
// Few data fields Which will not be able to serialize
transient private String Transient_Variable = "this is a transient instance field";
private Thread Thread_Class;
private static Object readIn() throws IOException, ClassNotFoundException {
ObjectInputStream Object_Input_Stream =
new ObjectInputStream(new FileInputStream(new File(File_Name)));
return Object_Input_Stream.readObject();
}
private static void writeOut(java.io.Serializable object) throws IOException {
ObjectOutputStream Object_Output_Stream =
new ObjectOutputStream(new FileOutputStream(new File(File_Name)));
Object_Output_Stream.writeObject(object);
Object_Output_Stream.close();
}
@Override
public String toString() {
return "Example Class:- final static fileName is: " + File_Name + ", final static logger is: "
+ logger_File + ", the non-final static staticVariable is: " + Static_Variable
+ ", the instance intVariable is: " + Integer_Variable
+ ", the transient instance Variable is: " + Transient_Variable
+ ", the non-serializable instance field threadClass is : " + Thread_Class;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// Serialization
Example Demo = new Example();
Demo.Integer_Variable = 1;
Static_Variable = "this is the static variable";
writeOut(Demo);
System.out.println("Example Class to be saved: " + Demo);
// De-serialization
System.out.println("Example Class deserialized: " + readIn());
}
}
Wenn die Klasse Serializable
nicht explizit eine SerialVersionUID
deklariert, berechnet die Laufzeitumgebung die Standard-SerialVersionUID
für diese Klasse basierend auf den Aspekten. Sehen wir uns nun die Ausgabe für den obigen Code an.
Example Class to be saved: Example Class:- final static fileName is: ExampleClassBytes.ser, final static logger is: java.util.logging.LogManager$RootLogger@27973e9b, the non-final static staticVariable is: this is the static variable, the instance intVariable is: 1, the transient instance Variable is: this is a transient instance field, the non-serializable instance field threadClass is : null
Example Class deserialized: Example Class:- final static fileName is: ExampleClassBytes.ser, final static logger is: java.util.logging.LogManager$RootLogger@27973e9b, the non-final static staticVariable is: this is the static variable, the instance intVariable is: 1, the transient instance Variable is: null, the non-serializable instance field threadClass is : null
Einige wichtige Punkte zur SerialVersionUID
basierend auf obigem Szenario:
- Die statischen und transienten Felder werden während der Serialisierung ignoriert, und nach der Deserialisierung werden die transienten und nicht statischen Endfelder null.
- Für die Serialisierung müssen wir die
IOException
behandeln, und für die Deserialisierung müssen wir dieIOException
undClassNotFoundException
behandeln. Das bedeutet, dass der deserialisierte Klassentyp im Klassenpfad enthalten sein sollte. - Für die Serialisierung und Deserialisierung werden die Methoden
ObjectInputStream.readObject()
undObjectOutputStream.writeObject(object)
verwendet. - Serialisierung und Deserialisierung können zum Klonen und Kopieren der Objekte verwendet werden, was vergleichsweise langsamer ist als normale Klonvorgänge.
- Die nicht initialisierten, nicht serialisierbaren und nicht transienten Instanzen werden toleriert.
- Beim Modifizieren der Klasse, die
java.io.Serializable
implementiert, müssen wir vorsichtig sein, denn wenn eine Klasse keineSerialVersionUID
enthält, dann wird vom Compiler eineSerialVersionUID
generiert. - Die Berechnung der
SerialVersionUID
basiert nicht nur auf den Feldern, sondern auch auf anderen Aspekten wie Konstruktoren, Implement-Klauseln usw. Das heisst, wir sollten explizit eineSerialVersionUID
deklarieren, was auch die Abwärtskompatibilität gewährleistet.
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn Facebook