views:

311

answers:

2

This question is an exact duplicate of:

http://stackoverflow.com/questions/888335/why-generate-long-serialversionuid

Ironically, answered by Michael Bogswardt as well.


Michael Bogswardt's answer to generating a serialVersionUID got me thinking. Is there any reason to generate a proper serialVersionUID like eclipse and IDEA (or just plain serialver)? Or is plugging in a 1L just as good?

+9  A: 

Once you write a number (any number) in there, it's your responsability to bump it when you make compatibility-breaking changes to the class (e.g. changing a JavaDoc doesn't break it, adding a property definitely does).

If you avoid specifying a serialVersionUID, javac will put there something unique like the hash of the class.

When does it matter? When you serialize stuff to disk and want to load it later with a different version of your program. Or when two instances which may be of different versions need to exchange serialized data over the wire.

If you don't use actual serialization and your class is Serializable just because it inherits that interface, then avoiding a serialVersionUID is the easiest and most safe thing to do. Same if you do serialize but don't really need to be compatible with the past, also in that case avoiding the value is the safest thing to do.

If, on the other hand, you need to load stuff produced with past revisions (either remotely or by yourself, from a long-forgotten file on disk) then you need to have that value and take much care to bump the number when (and only when) you do actually break the compatibility.

ADDED after second comment (by Robin):

Doesn't answer the actual question.

Err, right. I guess that's a: no as far as I know the actual number means nothing, it only has to be different from all previous value it had in previous times, when it is no more compatible with them.

Also, you should always declare a serialVersionUID for your Serializable classes

As a general suggestion, I think avoiding it is a better solution: most of the time you don't need to talk with JVM of different vendors, you don't need to de-serialize data from long past or actually need that compatibility check, most of the times serialized object are very short-lived.

Of course that can be very different for different projects and when you do have long-lived serialized object, well, you have to take the burden of defining those UID, and maintaining them correctly.

But as an absent UID means "fail fast, catch errors", while using 1L (or any other constant number) usually means "the class changes, you didn't remember to update it, problems arise later", then as a general suggestion, I think the first is a better default.

lapo
Thanks for the response, but my question was a little different. It was about if (once you decided to use one) there is an advantage between -5797392465261933639L (a real one from our project) and a plain 1L
Yishai
Doesn't answer the actual question. Also, you should always declare a serialVersionUID for your Serializable classes, the reasons are given in the javadoc for Serializable, at the very end. Basically, different compilers can produce different values for the same code. http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html
Robin
@lapo - If you are going to refute suggestions or other points in the comments, you should do so in the comments as well. Otherwise others reading your answer will not be able to follow the flow of events. It also makes it difficult for one to make further comments based on your replies.
Robin
I used to think the same with regards to explicitly declaring the serialVersionUID, until I found out that the algorithm for calculating it can change between compilers. This means the chances of things breaking increases greatly. As for the multiple JVM's this is common in a distributed environment with remote communications. This is where the serialization errors will occur between client and server, or server and server. Storing the objects is not the most common usage for serialization, transporting them over a network is. Also, different compiles run on the same JVM can cause issues.
Robin
What do you mean "between compilers"? Sun vs IBM VMs or Sun JVM 1.5.0_13 vs Sun JVM 1.6.0? It never broke for that reason to me, but maybe I was just lucky (also I use more SOAP than serialization, across the network, usually).
lapo
@lapo, yes it can break across those. If it didn't, it was just coincidence. The spec allows it to be different.
Yishai
@Yishai: in Java word "allowed" is usually quite different from "happens", retro-compatibility is taken to an extreme (how many method deprecated since 1.1 would be allowed to be deleted, ought to be deleted, and yet are there?)... but yes, ok, the point is taken, whether one considers that a problem or not depends on the specific usage he needs.
lapo
+3  A: 

The only use of a "real" serialVersionUID is for backword compatibility. If it is a new class, use whatever numbering system you want.

Personally I think using a simple number scheme will make it easier to read and compare changes of that number between versions. The hash value creating by the tooling is fine for a machine, but not human friendly. A simple one up numbering scheme works great for both, after all, the machine doesn't care one way or the other.

Robin
+1 on this. We actually set serialVersionUID to 1 for all classes and then declare the actual version as an int field. Our read/write methods save this version number explicitly and take the appropriate action when the version changes. Got this technique from an O'Reilly book.
Fortyrunner