What is a serialVersionUID and why should I use it?
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 differentserialVersionUID
than that of the corresponding sender's class, then deserialization will result in anInvalidClassException
. A serializable class can declare its ownserialVersionUID
explicitly by declaring a field namedserialVersionUID
that must be static, final, and of typelong
:
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 defaultserialVersionUID
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 declareserialVersionUID
values, since the defaultserialVersionUID
computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpectedInvalidClassExceptions
during deserialization. Therefore, to guarantee a consistentserialVersionUID
value across different java compiler implementations, a serializable class must declare an explicitserialVersionUID
value. It is also strongly advised that explicitserialVersionUID
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.
What is a serial version UID used for?
The serialVersionUID
is part of the black magic of the Java serialization API.
It is used to uniquely identify a version of the class so that when a class is de-serialized the version can be checked against the version of the class loaded by the ClassLoader
.
The serialization API will generate a serialVersionUID
itself if none is specified but this is then subject to random change by inconsequential changes (or at least ones that don't break serialization compatibility).
Adding the field yourself gives you control over this process - you decide when a change to the class should break de-serialization of older versions.
More information can be found in the JavaDocs for Serializable
.
In short, if you plan to serialize this class and then de-serialize it later - but after making some changes to code and recompiling etc - this field is more-or-less essential to guarantee that this will work as intended.
Is Java SerialVersionUid of 1L ok? Or does it need to be unique?
The class name is part of the serialized representation of an object. The serialVersionUID is only used for versioning the classes. So 1L is a valid value.
Note that if you don't plan to maintain the compatibility of serialization while evolving the class, serialVersionUID is useless, and you can just omit it. Having a serialVersionUID is useful when you want to make compatible changes to a class and still be able to read objects that were serialized using an older version of the class (or vice-versa). But that requires extreme care, and is far from being an easy task. You should generally avoid using serialization for long-term storage. If used for networking purpose, using the same exact classes for the client and the server (i.e. deploying both at once) is the easiest strategy.
Also note that you could easily prove your coworker that he's wrong by simply serializing and deserializing two objects of two different classes having both the same value (1L) as serialVersionUID. If his theory was true, the JVM would have no way of knowing how to deserialize the objects.
Why we use serialVersionUID during serialization
Let me quote an essence from similar and already answered question
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.
and
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).
I recommend you to visit that link and, as always, search the web.
Hope that helps.
Why SerialVersionUID is static
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.
What are the pros and cons of using serialVersionUID and @SuppressWarnings(serial) on classes implementing Serializable?
It boils down to this questions:
- Shall the serialized streams be read and written by the just same code or by different code?
"Different code" can mean several things:
- old versions vs. new versions
- two independent programs with perhaps old and new libraries
- more of stuff like that.
In these cases you should strongly adhere to the Serialization contracts - and this not done by just setting serialVersionUId
- usually you must also overwrite the methods for serialization and deserialization to cope with different versions.
If - on the other hand - the same program reads and writes the stuff for something like an internal cache and that cache can be rebuild from scratch on when the software is updated - then feel free to make your life as easy as you can.
Between these extremes are of course various shades of grey.
Related Topics
How to Create a Java String from the Contents of a File
Loop Doesn't See Value Changed by Other Thread Without a Print Statement
Convert a String Representation of a Hex Dump to a Byte Array Using Java
What's Wrong With Java Date & Time API
Why Is Java Vector (And Stack) Class Considered Obsolete or Deprecated
How to Convert a Byte Array to a Hex String in Java
Stringbuilder VS String Concatenation in Tostring() in Java
How to Deal With "Java.Lang.Outofmemoryerror: Java Heap Space" Error
How to Fix a Nosuchmethoderror
Validating Input Using Java.Util.Scanner
When Do You Use Java'S @Override Annotation and Why
What Is the Point of the Diamond Operator (≪≫) in Java
How to Resolve Classnotfoundexception
Difference Between ≪? Super T≫ and ≪? Extends T≫ in Java
What Are the Possible Values of the Hibernate Hbm2Ddl.Auto Configuration and What Do They Do