6

I have a discussion with a colleague about the serialVersionUID of serializable classes: He always start with a serialVersionUID = 1L and then increments it by one when there are some significant changes to the class.

The JDK classes always seem to use more complex, generated serialVersionUIDs like in the java.lang.String class:

private static final long serialVersionUID = -6849794470754667710L;

Now my colleague asks about the advantage of this kind of serialVersionUID versus much simpler serialVersionUID like 1L, 2L, 3L... ?

We also searched on SOF, but are not very satisfied with the answers given, for example in Why generate long serialVersionUID instead of a simple 1L?.

In my opinion the advantage of using generated IDs is that it does not need any information about the 'older' class versions. But when incrementing the IDs manually, you have to know the highest value so far. This might sound trivial (by just looking at the current serialVersionUID and increase it by 1) but could be more complex in bigger software projects, bigger development teams or in distributed environments.

Community
  • 1
  • 1
Sebastian S.
  • 1,545
  • 6
  • 24
  • 41
  • 2
    If you increment it when there are significant changes to the class, that means you accept that these changes make the new version of the class incompatible with older versions. In that case, not having a serialVersionUID at all is the least verbose and simplest solution. – JB Nizet Nov 15 '16 at 16:59
  • 4
    The serialVersionUID is best thought of as tracking the *compatible version of the serialized form* rather than the version of the class. Classes can be modified extensively without any change to the way state is written and read from the serialized form. As long as the class remains compatible with its serialized form, there is no reason to change the serialVersionUID (which is why the best practice is to explicitly specify it). – scottb Nov 15 '16 at 17:06
  • Guys don't get me wrong, I know how the serialization mechanism works and I don't have a problem with it. I just wonder about the advantage or disadvantage of generated serialVersionUIDs vs. incremented ones. – Sebastian S. Nov 17 '16 at 10:21

2 Answers2

1

The advantage of using a generated one is that it is compatible with the prior version of the class if it has escaped without a serialVersionUID into the wild.

Having said that, your colleague is almost certainly wrong to increment it. The serialVersionUID should only be changed at a point where you accept that the class has changed irretrievably and you deliberately want to introduce a serialization-incompatibility. The times when this occurs in nature are rare, being confined to the cases where you change the inheritance of the class or the types of member fields in an incompatible way. If you've decided to make a class Serializable you should already have accepted a regime in which that doesn't occur.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • To deal with versioning (and e.g. adding new fields to class) one should consider aproach with own version field. Like shown here: http://stackoverflow.com/questions/3678136/managing-several-versions-of-serialized-java-objects#answer-14946099 – szymond Nov 20 '16 at 11:10
  • @szymond Or inheritance. – user207421 Nov 20 '16 at 21:08
-1

This is an interesting question, to come right to the point: I don't know.

The SUID is part of the public API. Once you published an API which is used outside your control, like the JDK, you can't change this number without breaking compatibility.

So I can't see any advantage of using a number like 32432544354343L instead of 1L.

But for inhouse development I see a small advantage of starting with a number like 1L:

Lets say we have 3 jars of a RMI client-server application:

  • client.jar
  • server.jar
  • api.jar

In the api.jar there are some business classes like Song, Album, ... used by client and server, which a serializable.

Now we start with a SUID of 1L for some of these classes and after a release we change the internal format of one of these classes, so we increment the SUID to 2L.

Now the client and server components both needs to include the new api.jar. If we make a mistake and forget to update either the client or the server with the new api.jar dependency there will be an exception during deserializing. The message in the exception will include the incompatible SUIDs.

So here the number 1L and 2L are in the message. 2L > 1L, hence we know that the component uses the old api.jar. With IDE generated numbers like 123434534553L and 654642646363L we don't know which component uses the old api.jar.

But on the other hand even new JDK classes like LocalDate uses numbers like 123434534553L instead of a simpler one. In apache commons-lang there seems to be a mix, e.g. FastDateParser.java uses a simple 3L.

https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/time/FastDateParser.java

Strange...

coder
  • 1,415
  • 2
  • 12
  • 15
  • There will be an exception in deserialization anyway if the change is incompatible. Changing the `serialVersionUID` just to deliberately cause this exception, including cases where it may not really be necessary, doesn't make much sense. – user207421 Nov 20 '16 at 10:43