SerialVersionUID in Java
This tutorial demonstrates how to use SerialVersionUID
in Java.
SerialVersionUID
in Java
The SerialVersionUID
is used in serialization. Serialization is a process where we convert an object to a stream of bytes to store the data and send it somewhere, and deserialization is the reverse process.
During the serialization process, the Java runtime will associate a version number with each Serializable
class; that number is called SerialVersionUID
.
The SerialVersionUID
is used to verify that the sender and receiver of the serialized data have loaded the classes for that data and are compatible in terms of serialization.
For example, if a receiver has loaded a class for the object with a different SerialVersionUID
than the corresponding sender’s class, it will throw the InvalidClassException
.
We can declare our own SerialVersionUID
for the Serializable
class. The SerialVersionUID
will be declared as Static Final
and Long
type.
See the syntax:
private static final long serialVersionUID = 10L;
Let’s try an example that implements serialization and deserialization with the SerialVersionUID
. See example:
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());
}
}
If the Serializable
class does not explicitly declare a SerialVersionUID
, then the runtime will calculate the default SerialVersionUID
for that class based on the aspects. Now let’s see the output for the code above.
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
Some important points about the SerialVersionUID
based on the above scenario:
- The static and transient fields are ignored during the serialization, and after deserialization, the transient and non-static final fields will become null.
- For the serialization, we need to handle the
IOException
, and for the deserialization, we need toIOException
andClassNotFoundException
. That means the deserialized class type should be in the class path. - The methods
ObjectInputStream.readObject()
andObjectOutputStream.writeObject(object)
are used for the serialization and deserialization operation. - Serialization and deserialization can be used to clone and copy the objects, which is comparatively slower than regular cloning operations.
- The uninitialized, non-serializable, and non-transient instances are tolerated.
- While modifying the class that implements the
java.io.Serializable
, we must be careful because if a class does not contain aSerialVersionUID
, then aSerialVersionUID
will be generated by the compiler. - Calculating the
SerialVersionUID
is based not only on the fields but also on other aspects like constructors, implement clauses, etc. This means we should explicitly declare aSerialVersionUID
, which will also maintain backward compatibility.
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