Serialization version uid in Java - java

How is Serialization id stored in the instance of the object ?
The Serialization id we declare in Java is static field;and static fields are not serialized.
There should be some way to store the static final field then. How does java do it ?

The serialVersionUID is not stored in the instance of a "serialized" object, as it is an static field (it is part of the class, not part of the object).
Therefore, it is stored in the compiled bytecode if it is actually defined, otherwise it is computed. In the java specification's words:
If the class has defined serialVersionUID it is retrieved from the class. If the serialVersionUID is >not defined by the class, it is computed from the definition of the class in the virtual machine. If >the specified class is not serializable or externalizable, null is returned.
In the Stream Unique Identifiers section, the algorithm for such computation is explained.
This paragraph is noteworthy (that's why IDEs usually show a warning when a class implementing Serializable has not explicitly defined a serialVersionUID).
Note: It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.

If you look in the java.io.ObjectStreamClass there you can see that it is actually being serialized. The following method:
java.io.ObjectOutputStream.writeClassDescriptor(ObjectStreamClass)
calls a method which calls the following method:
java.io.ObjectStreamClass.getSerialVersionUID()
Which either computes the serialVersionUID or uses the one declared in the class and found before in the call to the following method:
java.io.ObjectStreamClass.getDeclaredSUID(Class)
So it seems that this static field is an exception from the rule that static fields are not being serialized.
How to read it is described here.

The serial version UID is not stored in objects; it's a static field so it is stored in the class definition. What happens is that when you serialize an object, information about its class has to be stored too; otherwise there would be no way to un-serialize the object. The information stored about the class includes its name and its serial version UID.
You can read the entire protocol here: http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html
In summary, the entry for a new object is exactly:
newObject:
TC_OBJECT classDesc newHandle classdata[]
Here classDesc is a descriptor of the class which can be either a declaration of a new class, a null reference, or a reference to a previously declared class:
classDesc:
newClassDesc
nullReference
(ClassDesc)prevObject
The declaration of a new class establishes the class's name and serial version UID, a handle that can be used to refer to it later, and additional information on the class encoded as classDescInfo:
newClassDesc:
TC_CLASSDESC className serialVersionUID newHandle classDescInfo

The serialVersionUID is a special field used by the serialization runtime. It's all described in the Java Doc for java.lang.Serializable

Related

Tips to maintain serialVersionUID in inheritance structure [duplicate]

Eclipse issues warnings when a serialVersionUID is missing.
The serializable class Foo does not declare a static final
serialVersionUID field of type long
What is serialVersionUID and why is it important? Please show an example where missing serialVersionUID will cause a problem.
The docs for java.io.Serializable are probably about as good an explanation as you'll get:
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. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class — serialVersionUID fields are not useful as inherited members.
If you're serializing just because you have to serialize for the implementation's sake (who cares if you serialize for an HTTPSession, for instance...if it's stored or not, you probably don't care about de-serializing a form object), then you can ignore this.
If you're actually using serialization, it only matters if you plan on storing and retrieving objects using serialization directly. The serialVersionUID represents your class version, and you should increment it if the current version of your class is not backwards compatible with its previous version.
Most of the time, you will probably not use serialization directly. If this is the case, generate a default SerialVersionUID by clicking the quick fix option and don't worry about it.
I can't pass up this opportunity to plug Josh Bloch's book Effective Java (2nd Edition). Chapter 10 is an indispensible resource on Java serialization.
Per Josh, the automatically-generated UID is generated based on a class name, implemented interfaces, and all public and protected members. Changing any of these in any way will change the serialVersionUID. So you don't need to mess with them only if you are certain that no more than one version of the class will ever be serialized (either across processes or retrieved from storage at a later time).
If you ignore them for now, and find later that you need to change the class in some way but maintain compatibility w/ old version of the class, you can use the JDK tool serialver to generate the serialVersionUID on the old class, and explicitly set that on the new class. (Depending on your changes you may need to also implement custom serialization by adding writeObject and readObject methods - see Serializable javadoc or aforementioned chapter 10.)
You can tell Eclipse to ignore these serialVersionUID warnings:
Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems
In case you didn't know, there are a lot of other warnings you can enable in this section (or even have some reported as errors), many are very useful:
Potential Programming Problems: Possible accidental boolean assignment
Potential Programming Problems: Null pointer access
Unnecessary code: Local variable is never read
Unnecessary code: Redundant null check
Unnecessary code: Unnecessary cast or 'instanceof'
and many more.
serialVersionUID facilitates versioning of serialized data. Its value is stored with the data when serializing. When de-serializing, the same version is checked to see how the serialized data matches the current code.
If you want to version your data, you normally start with a serialVersionUID of 0, and bump it with every structural change to your class which alters the serialized data (adding or removing non-transient fields).
The built-in de-serialization mechanism (in.defaultReadObject()) will refuse to de-serialize from old versions of the data. But if you want to you can define your own readObject()-function which can read back old data. This custom code can then check the serialVersionUID in order to know which version the data is in and decide how to de-serialize it. This versioning technique is useful if you store serialized data which survives several versions of your code.
But storing serialized data for such a long time span is not very common. It is far more common to use the serialization mechanism to temporarily write data to for instance a cache or send it over the network to another program with the same version of the relevant parts of the codebase.
In this case you are not interested in maintaining backwards compatibility. You are only concerned with making sure that the code bases which are communicating indeed have the same versions of relevant classes. In order to facilitate such a check, you must maintain the serialVersionUID just like before and not forget to update it when making changes to your classes.
If you do forget to update the field, you might end up with two different versions of a class with different structure but with the same serialVersionUID. If this happens, the default mechanism (in.defaultReadObject()) will not detect any difference, and try to de-serialize incompatible data. Now you might end up with a cryptic runtime error or silent failure (null fields). These types of errors might be hard to find.
So to help this usecase, the Java platform offers you a choice of not setting the serialVersionUID manually. Instead, a hash of the class structure will be generated at compile-time and used as id. This mechanism will make sure that you never have different class structures with the same id, and so you will not get these hard-to-trace runtime serialization failures mentioned above.
But there is a backside to the auto-generated id strategy. Namely that the generated ids for the same class might differ between compilers (as mentioned by Jon Skeet above). So if you communicate serialized data between code compiled with different compilers, it is recommended to maintain the ids manually anyway.
And if you are backwards-compatible with your data like in the first use case mentioned, you also probably want to maintain the id yourself. This in order to get readable ids and have greater control over when and how they change.
What is a serialVersionUID and why should I use it?
SerialVersionUID is a unique identifier for each class, JVM uses it to compare the versions of the class ensuring that the same class was used during Serialization is loaded during Deserialization.
Specifying one gives more control, though JVM does generate one if you don't specify. The value generated can differ between different compilers. Furthermore, sometimes you just want for some reason to forbid deserialization of old serialized objects [backward incompatibility], and in this case you just have to change the serialVersionUID.
The javadocs for Serializable say:
the default serialVersionUID computation is highly sensitive to class
details that may vary depending on compiler implementations, and can
thus result in unexpected InvalidClassExceptions during
deserialization.
Therefore, you must declare serialVersionUID because it give us more control.
This article has some good points on the topic.
Original question has asked for 'why is it important' and 'example' where this Serial Version ID would be useful. Well I have found one.
Say you create a Car class, instantiate it, and write it out to an object stream. The flattened car object sits in the file system for some time. Meanwhile, if the Car class is modified by adding a new field. Later on, when you try to read (i.e. deserialize) the flattened Car object, you get the java.io.InvalidClassException – because all serializable classes are automatically given a unique identifier. This exception is thrown when the identifier of the class is not equal to the identifier of the flattened object. If you really think about it, the exception is thrown because of the addition of the new field. You can avoid this exception being thrown by controlling the versioning yourself by declaring an explicit serialVersionUID. There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated). So, it is best practice to add your own serialVersionUID to your Serializable classes as soon as you create them as shown below:
public class Car {
static final long serialVersionUID = 1L; //assign a long value
}
First I need to explain what serialization is.
Serialization allows to convert an object to a stream, for sending that object over the network OR Save to file OR save into DB for letter usage.
There are some rules for serialization.
An object is serializable only if its class or its superclass implements the Serializable interface
An object is serializable (itself implements the Serializable interface) even if its superclass is not. However, the first superclass in the hierarchy of the serializable class, that does not implements Serializable interface, MUST have a no-arg constructor. If this is violated, readObject() will produce a java.io.InvalidClassException in runtime
All primitive types are serializable.
Transient fields (with transient modifier) are NOT serialized, (i.e., not saved or restored). A class that implements Serializable must mark transient fields of classes that do not support serialization (e.g., a file stream).
Static fields (with static modifier) are not serialized.
When Object is serialized, Java Runtime associates the serial version number aka, the serialVersionID.
Where we need serialVersionID:
During the deserialization to verify that sender and receiver are compatible with respect to serialization. If the receiver loaded the class with a different serialVersionID then deserialization will end with InvalidClassCastException.
A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long.
Let's try this with an example.
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;
public String getEmpName() {
return name;
}
public void setEmpName(String empname) {
this.empname = empname;
}
public byte getEmpAge() {
return empage;
}
public void setEmpAge(byte empage) {
this.empage = empage;
}
public String whoIsThis() {
return getEmpName() + " is " + getEmpAge() + "years old";
}
}
Create Serialize Object
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
Employee employee = new Employee();
employee.setEmpName("Jagdish");
employee.setEmpAge((byte) 30);
FileOutputStream fout = new
FileOutputStream("/users/Jagdish.vala/employee.obj");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Process complete");
}
}
Deserialize the object
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Employee employee = new Employee();
FileInputStream fin = new FileInputStream("/users/Jagdish.vala/employee.obj");
ObjectInputStream ois = new ObjectInputStream(fin);
employee = (Employee) ois.readObject();
ois.close();
System.out.println(employee.whoIsThis());
}
}
NOTE: Now change the serialVersionUID of the Employee class and save:
private static final long serialVersionUID = 4L;
And execute the Reader class. Not to execute the Writer class and you will get the exception.
Exception in thread "main" java.io.InvalidClassException:
com.jagdish.vala.java.serialVersion.Employee; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)
If you will never need to serialize your objects to byte array and send/store them, then you don't need to worry about it. If you do, then you must consider your serialVersionUID since the deserializer of the object will match it to the version of object its classloader has. Read more about it in the Java Language Specification.
If you get this warning on a class you don't ever think about serializing, and that you didn't declare yourself implements Serializable, it is often because you inherited from a superclass, which implements Serializable. Often then it would be better to delegate to such a object instead of using inheritance.
So, instead of
public class MyExample extends ArrayList<String> {
public MyExample() {
super();
}
...
}
do
public class MyExample {
private List<String> myList;
public MyExample() {
this.myList = new ArrayList<String>();
}
...
}
and in the relevant methods call myList.foo() instead of this.foo() (or super.foo()). (This does not fit in all cases, but still quite often.)
I often see people extending JFrame or such, when they really only need to delegate to this. (This also helps for auto-completing in a IDE, since JFrame has hundreds of methods, which you don't need when you want to call your custom ones on your class.)
One case where the warning (or the serialVersionUID) is unavoidable is when you extend from AbstractAction, normally in a anonymous class, only adding the actionPerformed-method. I think there shouldn't be a warning in this case (since you normally can't reliable serialize and deserialize such anonymous classes anyway accross different versions of your class), but I'm not sure how the compiler could recognize this.
To understand the significance of field serialVersionUID, one should understand how Serialization/Deserialization works.
When a Serializable class object is serialized Java Runtime associates a serial version no.(called as serialVersionUID) with this serialized object. At the time when you deserialize this serialized object Java Runtime matches the serialVersionUID of serialized object with the serialVersionUID of the class. If both are equal then only it proceeds with the further process of deserialization else throws InvalidClassException.
So we conclude that to make Serialization/Deserialization process successful the serialVersionUID of serialized object must be equivalent to the serialVersionUID of the class. In case if programmer specifies the serialVersionUID value explicitly in the program then the same value will be associated with the serialized object and the class, irrespective of the serialization and deserialzation platform(for ex. serialization might be done on platform like windows by using sun or MS JVM and Deserialization might be on different platform Linux using Zing JVM).
But in case if serialVersionUID is not specified by programmer then while doing Serialization\DeSerialization of any object, Java runtime uses its own algorithm to calculate it. This serialVersionUID calculation algorithm varies from one JRE to another. It is also possible that the environment where the object is serialized is using one JRE (ex: SUN JVM) and the environment where deserialzation happens is using Linux Jvm(zing). In such cases serialVersionUID associated with serialized object will be different than the serialVersionUID of class calculated at deserialzation environment. In turn deserialization will not be successful. So to avoid such situations/issues programmer must always specify serialVersionUID of Serializable class.
As for an example where the missing serialVersionUID might cause a problem:
I'm working on this Java EE application that is composed of a Web module that uses an EJB module. The web module calls the EJB module remotely and passes a POJO that implements Serializable as an argument.
This POJO's class was packaged inside the EJB jar and inside it's own jar in the WEB-INF/lib of the web module. They're actually the same class, but when I package the EJB module I unpack this POJO's jar to pack it together with the EJB module.
The call to the EJB was failing with the Exception below because I hadn't declared its serialVersionUID:
Caused by: java.io.IOException: Mismatched serialization UIDs : Source
(Rep.
IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588)
= 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52)
= 6227F23FA74A9A52
Don't bother, the default calculation is really good and suffice for 99,9999% of the cases. And if you run into problems, you can - as already stated - introduce UID's as the need arrise (which is highly unlikely)
I generally use serialVersionUID in one context: When I know it will be leaving the context of the Java VM.
I would know this when I to use ObjectInputStream and ObjectOutputStream for my application or if I know a library/framework I use will use it. The serialVersionID ensures different Java VMs of varying versions or vendors will inter-operate correctly or if it is stored and retrieved outside the VM for example HttpSession the session data can remain even during a restart and upgrade of the application server.
For all other cases, I use
#SuppressWarnings("serial")
since most of the time the default serialVersionUID is sufficient. This includes Exception, HttpServlet.
Field data represents some information stored in the class.
Class implements the Serializable interface,
so eclipse automatically offered to declare the serialVersionUID field. Lets start with value 1 set there.
If you don't want that warning to come, use this:
#SuppressWarnings("serial")
Why use SerialVersionUID inside Serializable class in Java?
During serialization, Java runtime creates a version number for a class, so that it can de-serialize it later. This version number is known as SerialVersionUID in Java.
SerialVersionUID is used to version serialized data. You can only de-serialize a class if it's SerialVersionUID matches with the serialized instance. When we don't declare SerialVersionUID in our class, Java runtime generates it for us but its not recommended. It's recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism.
When you declare a class as Serializable by implementing marker interface java.io.Serializable, Java runtime persist instance of that class into disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface.
see also Why use SerialVersionUID inside Serializable class in Java
SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch
Read more: http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
It would be nice if CheckStyle could verify that the serialVersionUID on a class that implements Serializable has a good value, i.e. that it matches what the serial version id generator would produce. If you have a project with lots of serializable DTOs, for example, remembering to delete the existing serialVersionUID and regenerate it is a pain, and currently the only way (that I know of) to verify this is to regenerate for each class and compare to the old one. This is very very painful.
If you want to amend a huge number of classes which had no serialVersionUID set in the first place while maintain the compatibility with the old classes, tools like IntelliJ Idea, Eclipse fall short as they generate random numbers and does not work on a bunch of files in one go. I come up the following bash script(I'm sorry for Windows users, consider buy a Mac or convert to Linux) to make amending serialVersionUID issue with ease:
base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes
while read f
do
clazz=${f//\//.}
clazz=${clazz/%.java/}
seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
perl -ni.bak -e "print $_; printf qq{%s\n}, q{ private $seruidstr} if /public class/" $src_dir/$f
done
you save the this script, say add_serialVersionUID.sh to you ~/bin. Then you run it in the root directory of your Maven or Gradle project like:
add_serialVersionUID.sh < myJavaToAmend.lst
This .lst includes the list of java files to add the serialVersionUID in the following format:
com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java
This script uses the JDK serialVer tool under hood. So make sure your $JAVA_HOME/bin is in the PATH.
This question is very well documented in Effective Java by Joshua Bloch. A very good book and a must read. I will outline some of the reasons below :
The serialization runtime comes up with a number called Serial version for each serializable class. This number is called serialVersionUID. Now there is some Math behind this number and it comes out based on the fields/methods that are defined in the class. For the same class the same version is generated every time. This number 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.
If the class is serializable you can also declare your own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long. Most IDE's like Eclipse help you generate that long string.
Each time an object is serialized the object is stamped with a version ID number for the object's class.This ID is called serialVersionUID and it is computed based on information about the class structure. Suppose you made an Employee class and it has version id #333 (assigned by JVM),Now when you will serialize the object of that class (Suppose Employee object), JVM will assign UID to it as #333.
Consider a situation - in the future you need to edit or change your class and in that case when you modify it, JVM will assign it a new UID (Suppose #444).
Now when you try to deserialize the employee object, JVM will compare serialized object's (Employee object) version ID(#333) with that of the class i.e #444(Since it was changed). On comparison JVM will find both version UID are different and hence Deserialization will fail.
Hence if serialVersionID for each class is defined by programmer itself. It will be same even if the class is evolved in future and hence JVM will always find that class is compatible with serialized object even though the class is changed. For more Info you can refer chapter 14 of HEAD FIRST JAVA.
A Simple Explanation:
Are you serializing data?
Serialization is basically writing class data to a file/stream/etc. De-serialization is reading that data back to a class.
Do you intend to go into production?
If you are just testing something with unimportant/fake data, then don't worry about it (unless you are testing serialization directly).
Is this the first version?
If so, set serialVersionUID=1L.
Is this the second, third, etc. prod version?
Now you need to worry about serialVersionUID, and should look into it in depth.
Basically, if you don't update the version correctly when you update a class you need to write/read, you will get an error when you try to read old data.
To tell the long story short this field is used to check if serialized data can be deserialized correctly. Serialization and deserialization are often made by different copies of program - for example server converts object to string and client converts received string to object. This field tells that both operates with same idea about what this object is. This field helps when:
you have many different copies of your program in different places (like 1 server and 100 clients). If you will change your object, alter your version number and forget to update one this clients, it will know that he is not capable of deserialization
you have stored your data in some file and later on you try to open it with updated version of your program with modified object - you will know that this file is not compatible if you keep your version right
When is it important?
Most obvious - if you add some fields to your object, older versions will not be able to use them because they do not have these fields in their object structure.
Less obvious - When you deserialize object, fields that where not present in string will be kept as NULL. If you have removed field from your object, older versions will keep this field as allways-NULL that can lead to misbehavior if older versions rely on data in this field (anyway you have created it for something, not just for fun :-) )
Least obvious - Sometimes you change the idea you put in some field's meaning. For example when you are 12 years old you mean "bicycle" under "bike", but when you are 18 you mean "motorcycle" - if your friends will invite you to "bike ride across city" and you will be the only one who came on bicycle, you will undestand how important it is to keep same meaning across fields :-)
'serialVersionUID' is a 64 bit number used to uniquely identify a class during deserialization process. When you serialize an object, serialVersionUID of the class also written to the file. Whenever you deserialize this object, java run time extract this serialVersionUID value from the serialized data and compare the same value associate with the class. If both do not match, then 'java.io.InvalidClassException' will be thrown.
If a serializable class do not explicitly declare a serialVersionUID, then serialization runtime will calculate serialVersionUID value for that class based on various aspects of the class like fields, methods etc.,, You can refer this link for demo application.
Firstly to answer your question, when we don't declare SerialVersionUID in our class, Java runtime generates it for us, but that process is sensitive to many class meta data including number of fields, type of fields, access modifier of fields, interface implemented by class etc. Therefore it is recommended to declare it ourselves and Eclipse is warning you about the same.
Serialization:
We often work with important objects whose state (data in the variables of the object) is so important that we can not risk to lose it due to power/system failures (or) network failures in case of sending the object state to other machine. The solution for this problem is named "Persistence" which simply means persisting (holding/saving) the data. Serialization is one of many other ways to achieve persistence (by saving data to disk/memory). When saving the state of the object, it is important to create an identity for the object, to be able to properly read it back (de-serialization). This unique identification is ID is SerialVersionUID.

Should I refrain from manually specifying serialVersionUID to make an object serializable? [duplicate]

Eclipse issues warnings when a serialVersionUID is missing.
The serializable class Foo does not declare a static final
serialVersionUID field of type long
What is serialVersionUID and why is it important? Please show an example where missing serialVersionUID will cause a problem.
The docs for java.io.Serializable are probably about as good an explanation as you'll get:
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. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class — serialVersionUID fields are not useful as inherited members.
If you're serializing just because you have to serialize for the implementation's sake (who cares if you serialize for an HTTPSession, for instance...if it's stored or not, you probably don't care about de-serializing a form object), then you can ignore this.
If you're actually using serialization, it only matters if you plan on storing and retrieving objects using serialization directly. The serialVersionUID represents your class version, and you should increment it if the current version of your class is not backwards compatible with its previous version.
Most of the time, you will probably not use serialization directly. If this is the case, generate a default SerialVersionUID by clicking the quick fix option and don't worry about it.
I can't pass up this opportunity to plug Josh Bloch's book Effective Java (2nd Edition). Chapter 10 is an indispensible resource on Java serialization.
Per Josh, the automatically-generated UID is generated based on a class name, implemented interfaces, and all public and protected members. Changing any of these in any way will change the serialVersionUID. So you don't need to mess with them only if you are certain that no more than one version of the class will ever be serialized (either across processes or retrieved from storage at a later time).
If you ignore them for now, and find later that you need to change the class in some way but maintain compatibility w/ old version of the class, you can use the JDK tool serialver to generate the serialVersionUID on the old class, and explicitly set that on the new class. (Depending on your changes you may need to also implement custom serialization by adding writeObject and readObject methods - see Serializable javadoc or aforementioned chapter 10.)
You can tell Eclipse to ignore these serialVersionUID warnings:
Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems
In case you didn't know, there are a lot of other warnings you can enable in this section (or even have some reported as errors), many are very useful:
Potential Programming Problems: Possible accidental boolean assignment
Potential Programming Problems: Null pointer access
Unnecessary code: Local variable is never read
Unnecessary code: Redundant null check
Unnecessary code: Unnecessary cast or 'instanceof'
and many more.
serialVersionUID facilitates versioning of serialized data. Its value is stored with the data when serializing. When de-serializing, the same version is checked to see how the serialized data matches the current code.
If you want to version your data, you normally start with a serialVersionUID of 0, and bump it with every structural change to your class which alters the serialized data (adding or removing non-transient fields).
The built-in de-serialization mechanism (in.defaultReadObject()) will refuse to de-serialize from old versions of the data. But if you want to you can define your own readObject()-function which can read back old data. This custom code can then check the serialVersionUID in order to know which version the data is in and decide how to de-serialize it. This versioning technique is useful if you store serialized data which survives several versions of your code.
But storing serialized data for such a long time span is not very common. It is far more common to use the serialization mechanism to temporarily write data to for instance a cache or send it over the network to another program with the same version of the relevant parts of the codebase.
In this case you are not interested in maintaining backwards compatibility. You are only concerned with making sure that the code bases which are communicating indeed have the same versions of relevant classes. In order to facilitate such a check, you must maintain the serialVersionUID just like before and not forget to update it when making changes to your classes.
If you do forget to update the field, you might end up with two different versions of a class with different structure but with the same serialVersionUID. If this happens, the default mechanism (in.defaultReadObject()) will not detect any difference, and try to de-serialize incompatible data. Now you might end up with a cryptic runtime error or silent failure (null fields). These types of errors might be hard to find.
So to help this usecase, the Java platform offers you a choice of not setting the serialVersionUID manually. Instead, a hash of the class structure will be generated at compile-time and used as id. This mechanism will make sure that you never have different class structures with the same id, and so you will not get these hard-to-trace runtime serialization failures mentioned above.
But there is a backside to the auto-generated id strategy. Namely that the generated ids for the same class might differ between compilers (as mentioned by Jon Skeet above). So if you communicate serialized data between code compiled with different compilers, it is recommended to maintain the ids manually anyway.
And if you are backwards-compatible with your data like in the first use case mentioned, you also probably want to maintain the id yourself. This in order to get readable ids and have greater control over when and how they change.
What is a serialVersionUID and why should I use it?
SerialVersionUID is a unique identifier for each class, JVM uses it to compare the versions of the class ensuring that the same class was used during Serialization is loaded during Deserialization.
Specifying one gives more control, though JVM does generate one if you don't specify. The value generated can differ between different compilers. Furthermore, sometimes you just want for some reason to forbid deserialization of old serialized objects [backward incompatibility], and in this case you just have to change the serialVersionUID.
The javadocs for Serializable say:
the default serialVersionUID computation is highly sensitive to class
details that may vary depending on compiler implementations, and can
thus result in unexpected InvalidClassExceptions during
deserialization.
Therefore, you must declare serialVersionUID because it give us more control.
This article has some good points on the topic.
Original question has asked for 'why is it important' and 'example' where this Serial Version ID would be useful. Well I have found one.
Say you create a Car class, instantiate it, and write it out to an object stream. The flattened car object sits in the file system for some time. Meanwhile, if the Car class is modified by adding a new field. Later on, when you try to read (i.e. deserialize) the flattened Car object, you get the java.io.InvalidClassException – because all serializable classes are automatically given a unique identifier. This exception is thrown when the identifier of the class is not equal to the identifier of the flattened object. If you really think about it, the exception is thrown because of the addition of the new field. You can avoid this exception being thrown by controlling the versioning yourself by declaring an explicit serialVersionUID. There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated). So, it is best practice to add your own serialVersionUID to your Serializable classes as soon as you create them as shown below:
public class Car {
static final long serialVersionUID = 1L; //assign a long value
}
First I need to explain what serialization is.
Serialization allows to convert an object to a stream, for sending that object over the network OR Save to file OR save into DB for letter usage.
There are some rules for serialization.
An object is serializable only if its class or its superclass implements the Serializable interface
An object is serializable (itself implements the Serializable interface) even if its superclass is not. However, the first superclass in the hierarchy of the serializable class, that does not implements Serializable interface, MUST have a no-arg constructor. If this is violated, readObject() will produce a java.io.InvalidClassException in runtime
All primitive types are serializable.
Transient fields (with transient modifier) are NOT serialized, (i.e., not saved or restored). A class that implements Serializable must mark transient fields of classes that do not support serialization (e.g., a file stream).
Static fields (with static modifier) are not serialized.
When Object is serialized, Java Runtime associates the serial version number aka, the serialVersionID.
Where we need serialVersionID:
During the deserialization to verify that sender and receiver are compatible with respect to serialization. If the receiver loaded the class with a different serialVersionID then deserialization will end with InvalidClassCastException.
A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long.
Let's try this with an example.
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;
public String getEmpName() {
return name;
}
public void setEmpName(String empname) {
this.empname = empname;
}
public byte getEmpAge() {
return empage;
}
public void setEmpAge(byte empage) {
this.empage = empage;
}
public String whoIsThis() {
return getEmpName() + " is " + getEmpAge() + "years old";
}
}
Create Serialize Object
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
Employee employee = new Employee();
employee.setEmpName("Jagdish");
employee.setEmpAge((byte) 30);
FileOutputStream fout = new
FileOutputStream("/users/Jagdish.vala/employee.obj");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Process complete");
}
}
Deserialize the object
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Employee employee = new Employee();
FileInputStream fin = new FileInputStream("/users/Jagdish.vala/employee.obj");
ObjectInputStream ois = new ObjectInputStream(fin);
employee = (Employee) ois.readObject();
ois.close();
System.out.println(employee.whoIsThis());
}
}
NOTE: Now change the serialVersionUID of the Employee class and save:
private static final long serialVersionUID = 4L;
And execute the Reader class. Not to execute the Writer class and you will get the exception.
Exception in thread "main" java.io.InvalidClassException:
com.jagdish.vala.java.serialVersion.Employee; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)
If you will never need to serialize your objects to byte array and send/store them, then you don't need to worry about it. If you do, then you must consider your serialVersionUID since the deserializer of the object will match it to the version of object its classloader has. Read more about it in the Java Language Specification.
If you get this warning on a class you don't ever think about serializing, and that you didn't declare yourself implements Serializable, it is often because you inherited from a superclass, which implements Serializable. Often then it would be better to delegate to such a object instead of using inheritance.
So, instead of
public class MyExample extends ArrayList<String> {
public MyExample() {
super();
}
...
}
do
public class MyExample {
private List<String> myList;
public MyExample() {
this.myList = new ArrayList<String>();
}
...
}
and in the relevant methods call myList.foo() instead of this.foo() (or super.foo()). (This does not fit in all cases, but still quite often.)
I often see people extending JFrame or such, when they really only need to delegate to this. (This also helps for auto-completing in a IDE, since JFrame has hundreds of methods, which you don't need when you want to call your custom ones on your class.)
One case where the warning (or the serialVersionUID) is unavoidable is when you extend from AbstractAction, normally in a anonymous class, only adding the actionPerformed-method. I think there shouldn't be a warning in this case (since you normally can't reliable serialize and deserialize such anonymous classes anyway accross different versions of your class), but I'm not sure how the compiler could recognize this.
To understand the significance of field serialVersionUID, one should understand how Serialization/Deserialization works.
When a Serializable class object is serialized Java Runtime associates a serial version no.(called as serialVersionUID) with this serialized object. At the time when you deserialize this serialized object Java Runtime matches the serialVersionUID of serialized object with the serialVersionUID of the class. If both are equal then only it proceeds with the further process of deserialization else throws InvalidClassException.
So we conclude that to make Serialization/Deserialization process successful the serialVersionUID of serialized object must be equivalent to the serialVersionUID of the class. In case if programmer specifies the serialVersionUID value explicitly in the program then the same value will be associated with the serialized object and the class, irrespective of the serialization and deserialzation platform(for ex. serialization might be done on platform like windows by using sun or MS JVM and Deserialization might be on different platform Linux using Zing JVM).
But in case if serialVersionUID is not specified by programmer then while doing Serialization\DeSerialization of any object, Java runtime uses its own algorithm to calculate it. This serialVersionUID calculation algorithm varies from one JRE to another. It is also possible that the environment where the object is serialized is using one JRE (ex: SUN JVM) and the environment where deserialzation happens is using Linux Jvm(zing). In such cases serialVersionUID associated with serialized object will be different than the serialVersionUID of class calculated at deserialzation environment. In turn deserialization will not be successful. So to avoid such situations/issues programmer must always specify serialVersionUID of Serializable class.
As for an example where the missing serialVersionUID might cause a problem:
I'm working on this Java EE application that is composed of a Web module that uses an EJB module. The web module calls the EJB module remotely and passes a POJO that implements Serializable as an argument.
This POJO's class was packaged inside the EJB jar and inside it's own jar in the WEB-INF/lib of the web module. They're actually the same class, but when I package the EJB module I unpack this POJO's jar to pack it together with the EJB module.
The call to the EJB was failing with the Exception below because I hadn't declared its serialVersionUID:
Caused by: java.io.IOException: Mismatched serialization UIDs : Source
(Rep.
IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588)
= 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52)
= 6227F23FA74A9A52
Don't bother, the default calculation is really good and suffice for 99,9999% of the cases. And if you run into problems, you can - as already stated - introduce UID's as the need arrise (which is highly unlikely)
I generally use serialVersionUID in one context: When I know it will be leaving the context of the Java VM.
I would know this when I to use ObjectInputStream and ObjectOutputStream for my application or if I know a library/framework I use will use it. The serialVersionID ensures different Java VMs of varying versions or vendors will inter-operate correctly or if it is stored and retrieved outside the VM for example HttpSession the session data can remain even during a restart and upgrade of the application server.
For all other cases, I use
#SuppressWarnings("serial")
since most of the time the default serialVersionUID is sufficient. This includes Exception, HttpServlet.
Field data represents some information stored in the class.
Class implements the Serializable interface,
so eclipse automatically offered to declare the serialVersionUID field. Lets start with value 1 set there.
If you don't want that warning to come, use this:
#SuppressWarnings("serial")
Why use SerialVersionUID inside Serializable class in Java?
During serialization, Java runtime creates a version number for a class, so that it can de-serialize it later. This version number is known as SerialVersionUID in Java.
SerialVersionUID is used to version serialized data. You can only de-serialize a class if it's SerialVersionUID matches with the serialized instance. When we don't declare SerialVersionUID in our class, Java runtime generates it for us but its not recommended. It's recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism.
When you declare a class as Serializable by implementing marker interface java.io.Serializable, Java runtime persist instance of that class into disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface.
see also Why use SerialVersionUID inside Serializable class in Java
SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch
Read more: http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
It would be nice if CheckStyle could verify that the serialVersionUID on a class that implements Serializable has a good value, i.e. that it matches what the serial version id generator would produce. If you have a project with lots of serializable DTOs, for example, remembering to delete the existing serialVersionUID and regenerate it is a pain, and currently the only way (that I know of) to verify this is to regenerate for each class and compare to the old one. This is very very painful.
If you want to amend a huge number of classes which had no serialVersionUID set in the first place while maintain the compatibility with the old classes, tools like IntelliJ Idea, Eclipse fall short as they generate random numbers and does not work on a bunch of files in one go. I come up the following bash script(I'm sorry for Windows users, consider buy a Mac or convert to Linux) to make amending serialVersionUID issue with ease:
base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes
while read f
do
clazz=${f//\//.}
clazz=${clazz/%.java/}
seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
perl -ni.bak -e "print $_; printf qq{%s\n}, q{ private $seruidstr} if /public class/" $src_dir/$f
done
you save the this script, say add_serialVersionUID.sh to you ~/bin. Then you run it in the root directory of your Maven or Gradle project like:
add_serialVersionUID.sh < myJavaToAmend.lst
This .lst includes the list of java files to add the serialVersionUID in the following format:
com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java
This script uses the JDK serialVer tool under hood. So make sure your $JAVA_HOME/bin is in the PATH.
This question is very well documented in Effective Java by Joshua Bloch. A very good book and a must read. I will outline some of the reasons below :
The serialization runtime comes up with a number called Serial version for each serializable class. This number is called serialVersionUID. Now there is some Math behind this number and it comes out based on the fields/methods that are defined in the class. For the same class the same version is generated every time. This number 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.
If the class is serializable you can also declare your own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long. Most IDE's like Eclipse help you generate that long string.
Each time an object is serialized the object is stamped with a version ID number for the object's class.This ID is called serialVersionUID and it is computed based on information about the class structure. Suppose you made an Employee class and it has version id #333 (assigned by JVM),Now when you will serialize the object of that class (Suppose Employee object), JVM will assign UID to it as #333.
Consider a situation - in the future you need to edit or change your class and in that case when you modify it, JVM will assign it a new UID (Suppose #444).
Now when you try to deserialize the employee object, JVM will compare serialized object's (Employee object) version ID(#333) with that of the class i.e #444(Since it was changed). On comparison JVM will find both version UID are different and hence Deserialization will fail.
Hence if serialVersionID for each class is defined by programmer itself. It will be same even if the class is evolved in future and hence JVM will always find that class is compatible with serialized object even though the class is changed. For more Info you can refer chapter 14 of HEAD FIRST JAVA.
A Simple Explanation:
Are you serializing data?
Serialization is basically writing class data to a file/stream/etc. De-serialization is reading that data back to a class.
Do you intend to go into production?
If you are just testing something with unimportant/fake data, then don't worry about it (unless you are testing serialization directly).
Is this the first version?
If so, set serialVersionUID=1L.
Is this the second, third, etc. prod version?
Now you need to worry about serialVersionUID, and should look into it in depth.
Basically, if you don't update the version correctly when you update a class you need to write/read, you will get an error when you try to read old data.
To tell the long story short this field is used to check if serialized data can be deserialized correctly. Serialization and deserialization are often made by different copies of program - for example server converts object to string and client converts received string to object. This field tells that both operates with same idea about what this object is. This field helps when:
you have many different copies of your program in different places (like 1 server and 100 clients). If you will change your object, alter your version number and forget to update one this clients, it will know that he is not capable of deserialization
you have stored your data in some file and later on you try to open it with updated version of your program with modified object - you will know that this file is not compatible if you keep your version right
When is it important?
Most obvious - if you add some fields to your object, older versions will not be able to use them because they do not have these fields in their object structure.
Less obvious - When you deserialize object, fields that where not present in string will be kept as NULL. If you have removed field from your object, older versions will keep this field as allways-NULL that can lead to misbehavior if older versions rely on data in this field (anyway you have created it for something, not just for fun :-) )
Least obvious - Sometimes you change the idea you put in some field's meaning. For example when you are 12 years old you mean "bicycle" under "bike", but when you are 18 you mean "motorcycle" - if your friends will invite you to "bike ride across city" and you will be the only one who came on bicycle, you will undestand how important it is to keep same meaning across fields :-)
'serialVersionUID' is a 64 bit number used to uniquely identify a class during deserialization process. When you serialize an object, serialVersionUID of the class also written to the file. Whenever you deserialize this object, java run time extract this serialVersionUID value from the serialized data and compare the same value associate with the class. If both do not match, then 'java.io.InvalidClassException' will be thrown.
If a serializable class do not explicitly declare a serialVersionUID, then serialization runtime will calculate serialVersionUID value for that class based on various aspects of the class like fields, methods etc.,, You can refer this link for demo application.
Firstly to answer your question, when we don't declare SerialVersionUID in our class, Java runtime generates it for us, but that process is sensitive to many class meta data including number of fields, type of fields, access modifier of fields, interface implemented by class etc. Therefore it is recommended to declare it ourselves and Eclipse is warning you about the same.
Serialization:
We often work with important objects whose state (data in the variables of the object) is so important that we can not risk to lose it due to power/system failures (or) network failures in case of sending the object state to other machine. The solution for this problem is named "Persistence" which simply means persisting (holding/saving) the data. Serialization is one of many other ways to achieve persistence (by saving data to disk/memory). When saving the state of the object, it is important to create an identity for the object, to be able to properly read it back (de-serialization). This unique identification is ID is SerialVersionUID.

serialVersionUID used by multiple entity classes in java with the same value

I found that many of the serialVersionUID of the entity classes in my project use the same value.
Now,there is no problem with my project, CURD is OK, but I think it is abnormal to use same value.
Is there a problem?
There won't be any problem, as the serial number works per class.
The compiler uses the serialVersionUID to compare the versions of the class to guarantee that the same version of that class was used for serializing it when you try to deserialize it.
The serialVersionUID facilitates the versioning of serialized data. If you update some of those classes, you'll be able to change their serial version in order to avoid any deserialization with an older version of the class: As the UIDs won't match, the deserialization won't be successful. This guarantees data consistency through different versions of the serialized elements.
No problem
In resume: There's no issue if more than a class hold the same SerialVersionUID (f.e: 1L), because as said, it works per class (there's no "duplicate version UID classes" mechanism involved here). It's just as correct as two elements that were updated independently and now both hold, as a coincidence, 696969L as their serial id: it's just each one's version number.
Declaring a permanent value, for example, 1L, is like telling the compiler: trust me, this class didn't change, just deserialize it.
1L is also the default serial version UID given to classes that implement the Serializable interface, meaning "this is the first version"; It will also become the last version for those classes that won't change.
Just to finish, the serialVersionUID of a class that does not implement Serializable is 0L.
Java Object Serialization Specification
If the class has defined serialVersionUID it is retrieved from the
class.
If the serialVersionUID is not defined by the class, it is
computed from the definition of the class in the virtual machine.
If the specified class is not serializable or externalizable, null is
returned. The lookupAny method behaves like the lookup method, except
that it returns the descriptor for any class, regardless of whether it
implements Serializable. The serialVersionUID of a class that does not
implement Serializable is 0L.

Serialization using serialVersionUid [duplicate]

Eclipse issues warnings when a serialVersionUID is missing.
The serializable class Foo does not declare a static final
serialVersionUID field of type long
What is serialVersionUID and why is it important? Please show an example where missing serialVersionUID will cause a problem.
The docs for java.io.Serializable are probably about as good an explanation as you'll get:
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. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class — serialVersionUID fields are not useful as inherited members.
If you're serializing just because you have to serialize for the implementation's sake (who cares if you serialize for an HTTPSession, for instance...if it's stored or not, you probably don't care about de-serializing a form object), then you can ignore this.
If you're actually using serialization, it only matters if you plan on storing and retrieving objects using serialization directly. The serialVersionUID represents your class version, and you should increment it if the current version of your class is not backwards compatible with its previous version.
Most of the time, you will probably not use serialization directly. If this is the case, generate a default SerialVersionUID by clicking the quick fix option and don't worry about it.
I can't pass up this opportunity to plug Josh Bloch's book Effective Java (2nd Edition). Chapter 10 is an indispensible resource on Java serialization.
Per Josh, the automatically-generated UID is generated based on a class name, implemented interfaces, and all public and protected members. Changing any of these in any way will change the serialVersionUID. So you don't need to mess with them only if you are certain that no more than one version of the class will ever be serialized (either across processes or retrieved from storage at a later time).
If you ignore them for now, and find later that you need to change the class in some way but maintain compatibility w/ old version of the class, you can use the JDK tool serialver to generate the serialVersionUID on the old class, and explicitly set that on the new class. (Depending on your changes you may need to also implement custom serialization by adding writeObject and readObject methods - see Serializable javadoc or aforementioned chapter 10.)
You can tell Eclipse to ignore these serialVersionUID warnings:
Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems
In case you didn't know, there are a lot of other warnings you can enable in this section (or even have some reported as errors), many are very useful:
Potential Programming Problems: Possible accidental boolean assignment
Potential Programming Problems: Null pointer access
Unnecessary code: Local variable is never read
Unnecessary code: Redundant null check
Unnecessary code: Unnecessary cast or 'instanceof'
and many more.
serialVersionUID facilitates versioning of serialized data. Its value is stored with the data when serializing. When de-serializing, the same version is checked to see how the serialized data matches the current code.
If you want to version your data, you normally start with a serialVersionUID of 0, and bump it with every structural change to your class which alters the serialized data (adding or removing non-transient fields).
The built-in de-serialization mechanism (in.defaultReadObject()) will refuse to de-serialize from old versions of the data. But if you want to you can define your own readObject()-function which can read back old data. This custom code can then check the serialVersionUID in order to know which version the data is in and decide how to de-serialize it. This versioning technique is useful if you store serialized data which survives several versions of your code.
But storing serialized data for such a long time span is not very common. It is far more common to use the serialization mechanism to temporarily write data to for instance a cache or send it over the network to another program with the same version of the relevant parts of the codebase.
In this case you are not interested in maintaining backwards compatibility. You are only concerned with making sure that the code bases which are communicating indeed have the same versions of relevant classes. In order to facilitate such a check, you must maintain the serialVersionUID just like before and not forget to update it when making changes to your classes.
If you do forget to update the field, you might end up with two different versions of a class with different structure but with the same serialVersionUID. If this happens, the default mechanism (in.defaultReadObject()) will not detect any difference, and try to de-serialize incompatible data. Now you might end up with a cryptic runtime error or silent failure (null fields). These types of errors might be hard to find.
So to help this usecase, the Java platform offers you a choice of not setting the serialVersionUID manually. Instead, a hash of the class structure will be generated at compile-time and used as id. This mechanism will make sure that you never have different class structures with the same id, and so you will not get these hard-to-trace runtime serialization failures mentioned above.
But there is a backside to the auto-generated id strategy. Namely that the generated ids for the same class might differ between compilers (as mentioned by Jon Skeet above). So if you communicate serialized data between code compiled with different compilers, it is recommended to maintain the ids manually anyway.
And if you are backwards-compatible with your data like in the first use case mentioned, you also probably want to maintain the id yourself. This in order to get readable ids and have greater control over when and how they change.
What is a serialVersionUID and why should I use it?
SerialVersionUID is a unique identifier for each class, JVM uses it to compare the versions of the class ensuring that the same class was used during Serialization is loaded during Deserialization.
Specifying one gives more control, though JVM does generate one if you don't specify. The value generated can differ between different compilers. Furthermore, sometimes you just want for some reason to forbid deserialization of old serialized objects [backward incompatibility], and in this case you just have to change the serialVersionUID.
The javadocs for Serializable say:
the default serialVersionUID computation is highly sensitive to class
details that may vary depending on compiler implementations, and can
thus result in unexpected InvalidClassExceptions during
deserialization.
Therefore, you must declare serialVersionUID because it give us more control.
This article has some good points on the topic.
Original question has asked for 'why is it important' and 'example' where this Serial Version ID would be useful. Well I have found one.
Say you create a Car class, instantiate it, and write it out to an object stream. The flattened car object sits in the file system for some time. Meanwhile, if the Car class is modified by adding a new field. Later on, when you try to read (i.e. deserialize) the flattened Car object, you get the java.io.InvalidClassException – because all serializable classes are automatically given a unique identifier. This exception is thrown when the identifier of the class is not equal to the identifier of the flattened object. If you really think about it, the exception is thrown because of the addition of the new field. You can avoid this exception being thrown by controlling the versioning yourself by declaring an explicit serialVersionUID. There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated). So, it is best practice to add your own serialVersionUID to your Serializable classes as soon as you create them as shown below:
public class Car {
static final long serialVersionUID = 1L; //assign a long value
}
First I need to explain what serialization is.
Serialization allows to convert an object to a stream, for sending that object over the network OR Save to file OR save into DB for letter usage.
There are some rules for serialization.
An object is serializable only if its class or its superclass implements the Serializable interface
An object is serializable (itself implements the Serializable interface) even if its superclass is not. However, the first superclass in the hierarchy of the serializable class, that does not implements Serializable interface, MUST have a no-arg constructor. If this is violated, readObject() will produce a java.io.InvalidClassException in runtime
All primitive types are serializable.
Transient fields (with transient modifier) are NOT serialized, (i.e., not saved or restored). A class that implements Serializable must mark transient fields of classes that do not support serialization (e.g., a file stream).
Static fields (with static modifier) are not serialized.
When Object is serialized, Java Runtime associates the serial version number aka, the serialVersionID.
Where we need serialVersionID:
During the deserialization to verify that sender and receiver are compatible with respect to serialization. If the receiver loaded the class with a different serialVersionID then deserialization will end with InvalidClassCastException.
A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long.
Let's try this with an example.
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;
public String getEmpName() {
return name;
}
public void setEmpName(String empname) {
this.empname = empname;
}
public byte getEmpAge() {
return empage;
}
public void setEmpAge(byte empage) {
this.empage = empage;
}
public String whoIsThis() {
return getEmpName() + " is " + getEmpAge() + "years old";
}
}
Create Serialize Object
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
Employee employee = new Employee();
employee.setEmpName("Jagdish");
employee.setEmpAge((byte) 30);
FileOutputStream fout = new
FileOutputStream("/users/Jagdish.vala/employee.obj");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Process complete");
}
}
Deserialize the object
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Employee employee = new Employee();
FileInputStream fin = new FileInputStream("/users/Jagdish.vala/employee.obj");
ObjectInputStream ois = new ObjectInputStream(fin);
employee = (Employee) ois.readObject();
ois.close();
System.out.println(employee.whoIsThis());
}
}
NOTE: Now change the serialVersionUID of the Employee class and save:
private static final long serialVersionUID = 4L;
And execute the Reader class. Not to execute the Writer class and you will get the exception.
Exception in thread "main" java.io.InvalidClassException:
com.jagdish.vala.java.serialVersion.Employee; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)
If you will never need to serialize your objects to byte array and send/store them, then you don't need to worry about it. If you do, then you must consider your serialVersionUID since the deserializer of the object will match it to the version of object its classloader has. Read more about it in the Java Language Specification.
If you get this warning on a class you don't ever think about serializing, and that you didn't declare yourself implements Serializable, it is often because you inherited from a superclass, which implements Serializable. Often then it would be better to delegate to such a object instead of using inheritance.
So, instead of
public class MyExample extends ArrayList<String> {
public MyExample() {
super();
}
...
}
do
public class MyExample {
private List<String> myList;
public MyExample() {
this.myList = new ArrayList<String>();
}
...
}
and in the relevant methods call myList.foo() instead of this.foo() (or super.foo()). (This does not fit in all cases, but still quite often.)
I often see people extending JFrame or such, when they really only need to delegate to this. (This also helps for auto-completing in a IDE, since JFrame has hundreds of methods, which you don't need when you want to call your custom ones on your class.)
One case where the warning (or the serialVersionUID) is unavoidable is when you extend from AbstractAction, normally in a anonymous class, only adding the actionPerformed-method. I think there shouldn't be a warning in this case (since you normally can't reliable serialize and deserialize such anonymous classes anyway accross different versions of your class), but I'm not sure how the compiler could recognize this.
To understand the significance of field serialVersionUID, one should understand how Serialization/Deserialization works.
When a Serializable class object is serialized Java Runtime associates a serial version no.(called as serialVersionUID) with this serialized object. At the time when you deserialize this serialized object Java Runtime matches the serialVersionUID of serialized object with the serialVersionUID of the class. If both are equal then only it proceeds with the further process of deserialization else throws InvalidClassException.
So we conclude that to make Serialization/Deserialization process successful the serialVersionUID of serialized object must be equivalent to the serialVersionUID of the class. In case if programmer specifies the serialVersionUID value explicitly in the program then the same value will be associated with the serialized object and the class, irrespective of the serialization and deserialzation platform(for ex. serialization might be done on platform like windows by using sun or MS JVM and Deserialization might be on different platform Linux using Zing JVM).
But in case if serialVersionUID is not specified by programmer then while doing Serialization\DeSerialization of any object, Java runtime uses its own algorithm to calculate it. This serialVersionUID calculation algorithm varies from one JRE to another. It is also possible that the environment where the object is serialized is using one JRE (ex: SUN JVM) and the environment where deserialzation happens is using Linux Jvm(zing). In such cases serialVersionUID associated with serialized object will be different than the serialVersionUID of class calculated at deserialzation environment. In turn deserialization will not be successful. So to avoid such situations/issues programmer must always specify serialVersionUID of Serializable class.
As for an example where the missing serialVersionUID might cause a problem:
I'm working on this Java EE application that is composed of a Web module that uses an EJB module. The web module calls the EJB module remotely and passes a POJO that implements Serializable as an argument.
This POJO's class was packaged inside the EJB jar and inside it's own jar in the WEB-INF/lib of the web module. They're actually the same class, but when I package the EJB module I unpack this POJO's jar to pack it together with the EJB module.
The call to the EJB was failing with the Exception below because I hadn't declared its serialVersionUID:
Caused by: java.io.IOException: Mismatched serialization UIDs : Source
(Rep.
IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588)
= 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52)
= 6227F23FA74A9A52
Don't bother, the default calculation is really good and suffice for 99,9999% of the cases. And if you run into problems, you can - as already stated - introduce UID's as the need arrise (which is highly unlikely)
I generally use serialVersionUID in one context: When I know it will be leaving the context of the Java VM.
I would know this when I to use ObjectInputStream and ObjectOutputStream for my application or if I know a library/framework I use will use it. The serialVersionID ensures different Java VMs of varying versions or vendors will inter-operate correctly or if it is stored and retrieved outside the VM for example HttpSession the session data can remain even during a restart and upgrade of the application server.
For all other cases, I use
#SuppressWarnings("serial")
since most of the time the default serialVersionUID is sufficient. This includes Exception, HttpServlet.
Field data represents some information stored in the class.
Class implements the Serializable interface,
so eclipse automatically offered to declare the serialVersionUID field. Lets start with value 1 set there.
If you don't want that warning to come, use this:
#SuppressWarnings("serial")
Why use SerialVersionUID inside Serializable class in Java?
During serialization, Java runtime creates a version number for a class, so that it can de-serialize it later. This version number is known as SerialVersionUID in Java.
SerialVersionUID is used to version serialized data. You can only de-serialize a class if it's SerialVersionUID matches with the serialized instance. When we don't declare SerialVersionUID in our class, Java runtime generates it for us but its not recommended. It's recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism.
When you declare a class as Serializable by implementing marker interface java.io.Serializable, Java runtime persist instance of that class into disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface.
see also Why use SerialVersionUID inside Serializable class in Java
SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch
Read more: http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
It would be nice if CheckStyle could verify that the serialVersionUID on a class that implements Serializable has a good value, i.e. that it matches what the serial version id generator would produce. If you have a project with lots of serializable DTOs, for example, remembering to delete the existing serialVersionUID and regenerate it is a pain, and currently the only way (that I know of) to verify this is to regenerate for each class and compare to the old one. This is very very painful.
If you want to amend a huge number of classes which had no serialVersionUID set in the first place while maintain the compatibility with the old classes, tools like IntelliJ Idea, Eclipse fall short as they generate random numbers and does not work on a bunch of files in one go. I come up the following bash script(I'm sorry for Windows users, consider buy a Mac or convert to Linux) to make amending serialVersionUID issue with ease:
base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes
while read f
do
clazz=${f//\//.}
clazz=${clazz/%.java/}
seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
perl -ni.bak -e "print $_; printf qq{%s\n}, q{ private $seruidstr} if /public class/" $src_dir/$f
done
you save the this script, say add_serialVersionUID.sh to you ~/bin. Then you run it in the root directory of your Maven or Gradle project like:
add_serialVersionUID.sh < myJavaToAmend.lst
This .lst includes the list of java files to add the serialVersionUID in the following format:
com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java
This script uses the JDK serialVer tool under hood. So make sure your $JAVA_HOME/bin is in the PATH.
This question is very well documented in Effective Java by Joshua Bloch. A very good book and a must read. I will outline some of the reasons below :
The serialization runtime comes up with a number called Serial version for each serializable class. This number is called serialVersionUID. Now there is some Math behind this number and it comes out based on the fields/methods that are defined in the class. For the same class the same version is generated every time. This number 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.
If the class is serializable you can also declare your own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long. Most IDE's like Eclipse help you generate that long string.
Each time an object is serialized the object is stamped with a version ID number for the object's class.This ID is called serialVersionUID and it is computed based on information about the class structure. Suppose you made an Employee class and it has version id #333 (assigned by JVM),Now when you will serialize the object of that class (Suppose Employee object), JVM will assign UID to it as #333.
Consider a situation - in the future you need to edit or change your class and in that case when you modify it, JVM will assign it a new UID (Suppose #444).
Now when you try to deserialize the employee object, JVM will compare serialized object's (Employee object) version ID(#333) with that of the class i.e #444(Since it was changed). On comparison JVM will find both version UID are different and hence Deserialization will fail.
Hence if serialVersionID for each class is defined by programmer itself. It will be same even if the class is evolved in future and hence JVM will always find that class is compatible with serialized object even though the class is changed. For more Info you can refer chapter 14 of HEAD FIRST JAVA.
A Simple Explanation:
Are you serializing data?
Serialization is basically writing class data to a file/stream/etc. De-serialization is reading that data back to a class.
Do you intend to go into production?
If you are just testing something with unimportant/fake data, then don't worry about it (unless you are testing serialization directly).
Is this the first version?
If so, set serialVersionUID=1L.
Is this the second, third, etc. prod version?
Now you need to worry about serialVersionUID, and should look into it in depth.
Basically, if you don't update the version correctly when you update a class you need to write/read, you will get an error when you try to read old data.
To tell the long story short this field is used to check if serialized data can be deserialized correctly. Serialization and deserialization are often made by different copies of program - for example server converts object to string and client converts received string to object. This field tells that both operates with same idea about what this object is. This field helps when:
you have many different copies of your program in different places (like 1 server and 100 clients). If you will change your object, alter your version number and forget to update one this clients, it will know that he is not capable of deserialization
you have stored your data in some file and later on you try to open it with updated version of your program with modified object - you will know that this file is not compatible if you keep your version right
When is it important?
Most obvious - if you add some fields to your object, older versions will not be able to use them because they do not have these fields in their object structure.
Less obvious - When you deserialize object, fields that where not present in string will be kept as NULL. If you have removed field from your object, older versions will keep this field as allways-NULL that can lead to misbehavior if older versions rely on data in this field (anyway you have created it for something, not just for fun :-) )
Least obvious - Sometimes you change the idea you put in some field's meaning. For example when you are 12 years old you mean "bicycle" under "bike", but when you are 18 you mean "motorcycle" - if your friends will invite you to "bike ride across city" and you will be the only one who came on bicycle, you will undestand how important it is to keep same meaning across fields :-)
'serialVersionUID' is a 64 bit number used to uniquely identify a class during deserialization process. When you serialize an object, serialVersionUID of the class also written to the file. Whenever you deserialize this object, java run time extract this serialVersionUID value from the serialized data and compare the same value associate with the class. If both do not match, then 'java.io.InvalidClassException' will be thrown.
If a serializable class do not explicitly declare a serialVersionUID, then serialization runtime will calculate serialVersionUID value for that class based on various aspects of the class like fields, methods etc.,, You can refer this link for demo application.
Firstly to answer your question, when we don't declare SerialVersionUID in our class, Java runtime generates it for us, but that process is sensitive to many class meta data including number of fields, type of fields, access modifier of fields, interface implemented by class etc. Therefore it is recommended to declare it ourselves and Eclipse is warning you about the same.
Serialization:
We often work with important objects whose state (data in the variables of the object) is so important that we can not risk to lose it due to power/system failures (or) network failures in case of sending the object state to other machine. The solution for this problem is named "Persistence" which simply means persisting (holding/saving) the data. Serialization is one of many other ways to achieve persistence (by saving data to disk/memory). When saving the state of the object, it is important to create an identity for the object, to be able to properly read it back (de-serialization). This unique identification is ID is SerialVersionUID.

Why SerialVersionUID is static

I am reading on Serialization in java.Java said that static variables are not serialized with the object.serialVersionUID is a must in serialization process.When an object is serialized,the serialVersionUID is serialized along with the other contents. This is one exception to the general serialization rule that, “static fields are not serialized”
Can anybody tell me why it is static.it can be nonstatic ?
Because any of the object variables/members can be accessed once Object is successfully created. You can't access Object variables without creating it. Now back to question, during deserialization, Object needs to be created from the data. If there's no way to check whether object is deserializable, there's no way to get the Object members.
For the same reason, UID is made as static.
serialVersionUID is static because it applies not to class instance but class itself. It is saved in ObjectOutputStream class descriptor.
It has to be static because it is mandated by the JRE to have it so. Reasoning may be simple, it can be accessed in a static way, without actually creating an object of the class.
From the javadocs:
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. A serializable class can declare its own
serialVersionUID explicitly by declaring a field named
"serialVersionUID" that must be static, final, and of type long:
It is an exception that it gets serialized . I believe it is static because it is bound to the class , not any instance of the class . All instances of the class should adhere to the same serialVersionUID. Again making it static means the run-time can actually get hold of that ID without creating any object, whereas prerequisite of de-serializing an object will be to ascertain the ID. When an object is serialized , the class name, the state of the object (non-static member variables) and the serialVersionUID are persisted .
First, you should understand what a serialVersionUID does.
From java.io.Serializable:
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.
The serialVersionUID determines compatibility between different versions of a class. Since the property is bound to the class, it has to be made static.
That serialVersionUID is a convention to verify that you have the same binary versions in both the serializer and deserializer and nothing is going to go wrong with outdated versions. Also, it could be the case where you have identical names for different kind of classes in the deserializer, so that serialVersionUID is like a sort od unique identifier.
That's why it must be static (so it is "bounded to the class, not to every instance) and "sent" along with the serialized data.

Categories

Resources