There are 3 ways to define the serialVersionUID :
1. private static final long serialVersionUID = 1L; (Default)
2. private static final long serialVersionUID = -
It's important to make clear the fact that having a class implement the Serializable
interface makes ALL fields not declared transient
part of the exported API of the class, whether or not those fields are declared private
.
In other words, implementing Serializable:
breaks encapsulation. If the class has any chance to become a successful, long-lived class then you must support the serialized form ... forever.
can seriously impair your ability to evolve that class, precisely because it is a part of its exported API. The alternative is to break backward compatibility.
can create security problems for your class and its application. Deserialization represents a way for making Java objects without a constructor, so it's possible to violate a class's invariants by providing rogue byte streams to the deserialization facility.
The serialVerionUID
should be thought of as a property of the serialized form. It is meant to convey to one JVM whether or not there a difference between the serialized form of a class instance that it is receiving and the serialized form of of that same class rendered (maybe) somewhere else.
You can see the potential problems that may occur if the serialized forms are different but the UIDs are the same. The receiving JVM will assume that the received serial form version between an old class and the new one are the same when they aren't and will dutifully go ahead and attempt to deserialize the byte stream.
TLDR: You shouldn't change the UID when you feel like it. You should change it when the serialized form of the class changes so that versions of software that use older versions of your class (with the different serialized form) will break instead of (possibly silently) doing the wrong thing. Not designing a good serialized form your classes will make it harder (even much harder) to provide backward compatibility for its clients. In the ideal case, the serialized form for a class persists throughout its entire evolution (and so its UID need never change).
Yes, I've seen code that defined serialVersionUID
like that too. I think it is a bad idea.
In this context there is only one "distinguished" value for the serialVersionUID
field; i.e. zero ... 0L
. Zero means "compute the version id at runtime by applying the standard algorithm" based on the actual class that you are serializing / deserializing. That means that whenever your code's effective serialization signature changes, the serialization / deserialization code will use a different version id. From a (big picture) type safety perspective, this is the safest thing to do, though it is also somewhat inefficient, and protentially more fragile.
What is the meaning?
The 1L
has no special meaning. It is just a number that will match 1L
as the "other" version id.
To my mind, you are better off either using 0L
, or a version number that was (at some point) generated using the standard algorithm.
If you use 0L
, then you get definite deserialization exceptions if classes change in ways that could be source of problems. If you need this, it is a good thing.
On the other hand you use a generated version id, you (the programmer) can make your own decision about when to regenerate the id. And when you do decide to regenerate, the id will only change if the class signature has changed. (If classes representation etc hasn't changed, the regenerated signature should be identical to the original one!) And when the id does change, you can think about whether to add custom methods ('readObject', etc) to deal with the incompatibility.
However, if you use 1L
, you can't tell if the version id needs to change without checking your code history, and comparing the old / new versions of the classes ... back as far as you need to.
Is that useful?
It depends on what you consider "useful" to mean. If you think it is a good thing to hard wire the version id to "trust me, it is ok", then 1L
is useful.
My recollection is that some versions of Eclipse offer 1L
as one of the possible auto-corrections for a missing serialVersionUID
field warning. That is probable where the instances you see have come from.