Tuesday, 21 January 2014

java.io.Serializable and serialVersionUID explained

When you mark a class as Serializable, Eclipse (perhaps other IDEs, too) will issue a warning and provide you with a set of options: One (1) is to ignore the warning and just carry on, (2) is to let the IDE assist you with generation of a serialVersionUID (actually generated by your JDK), and the last option (3) is for the IDE to assign a default serialVersionUID to your class. Let's explore these options and see which one to pick and why.


Every Java class implementing the marker interface java.io.Serializable must define a static final serialVersionUID of type long (any access modifier allowed). If not provided by the programmer, the JVM will generate one at runtime.

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.

No serialVersionUID

If a class does not define this constant and is serialized using the standard Java serialization process, the serialVersionUID generated at runtime will be used and stored in the serialized output. If we later decide to add this constant to the Serializable class, and choose to use a default of 1L, any previously serialized objects of this same class, although in theory compatible, will fail to deserialize with a InvalidClassException.

Generated serialVersionUID

Therefore, if there are already serialized copies of objects that are using a JVM-provided serialVersionUID, it’s best to select the option to generate the serialVersionUID in you IDE, which will come up with an UID matching the UID of objects previously serialized. This is especially important if we want to make compatible changes to the class and not break the current deserialization process. First, generate a serialVersionUID from the class marked Serializable that does not explicitly define this constant (use your IDE, or the JDK utility serialver to generate the correct UID), then add fields (or other compatible changes) to the class then recompile. The compiler will bake your explicitly defined serialVersionUID into the class definition and your new code will be able to deserialize both the old and the new versions of the serialized objects, as these will both have a matching serialVersionUID.

Note, however, that different JVM implementations compute this number differently, so the UID of source/destination might not match; thus serialization between different systems would not work.

Default serialVersionUID

On the other hand, we have the option to use default serialVersionUID numbers. These are a good choice for new Serializable classes. Note that every time we make incompatible changes to a Serializable class, we must remember to update the serialVersionUID number. This is easier to do when we explicitly define a small version number, such as 1L. When creating a new Serializable class, there’s no reason to generate the serialVersionUID, as there won’t be any already serialized objects of this new class. Define a default serialVersionUID of 1L and remember to update this version number every time you make an incompatible change to the class.

No comments:

Post a Comment