4

There is a java class in our code which implements Serializable.It already has a serialVersionUUId defined in the class. Apart from that we also have another

static final String sVersion which is an integer.This class implements the readObject and writeObject api . In the readObject API it populates all the member variables using the InputStream and in the writeObject API , it gets an OutputStream and calls the writeObject method .

Now i need to add an array of booleans as a property for this class. Should i change the serialVersionUUID? What is the effect that would happen if i change/not change the version id? what is the best practice?Im trying to get into Effective java by joshua bloch , but need a quick easy to digest answer for this.

Thanks

Barry
  • 1,585
  • 3
  • 22
  • 35

2 Answers2

2

This class implements the readObject and writeObject api. In the readObject API it populates all the member variables using the InputStream and in the writeObject API , it gets an OutputStream and calls the writeObject method.

Why? That's the default action if you don't provide those methods at all. [Although I don't know what exactly you mean by 'gets an OutputStream`, unless you mean the one provided as a parameter.]

However now that you're here, all you have to do in readObject() is attempt to read the new fields and catch the exception that's thrown if they aren't there (OptionalDataException?), and in writeObject() write out the extra field.

Don't change the serialVersionUID. You should instead explore the extensive object versioning support of Serialization, (a) to ensure that the class really is now serialization-incompatible, which per the specification is quite difficult to achieve; (b) to try a scheme such as custom read/writeObject() methods, readResolve/writeReplace() methods, serializableFields declarations, etc, to make sure that the stream remains compatible. Changing the actual serialVersionUID is a last resort, a counsel of despair.

Before proceeding any further you need to have a really good look at the Object Versioning section of the Object Serialization Specification. Serialization has a lot more support for class evolution than most people appear to be aware of, including other respondents to this question and the questions that they have linked to.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks for the link. And also for mentioning that changing the actual serialVersionUID is "the last resort" :) – Barry Dec 12 '12 at 01:29
0

If there is a possibility that you might end up trying to deserialize an incompatible instance of the class, then yes, you should definitely update the serialVersionUID. If, on the other hand, your program always serializes and deserializes the data without saving it to persistent storage or the contract between your class and its callers can still be guaranteed, then you don't need to change the serialVersionUID.

See https://stackoverflow.com/a/286254/44737 and https://stackoverflow.com/a/285827/44737 for more information.

Community
  • 1
  • 1
rob
  • 6,147
  • 2
  • 37
  • 56
  • well , i want my class to be compatible with the older versions as well. Hence i thought i should not change the versionId after reading the links that you sent me. But i get an OptinalDataException when the read object method tries to read the new boolean array – Barry Dec 12 '12 at 00:22
  • and when i look into OptionalDataException what i understand is An attempt was made to read past the end of data consumable by a class-defined readObject or readExternal method. In this case, the OptionalDataException's eof field is set to true, and the length field is set to 0. – Barry Dec 12 '12 at 00:25
  • "If there is a possibility that you might end up trying to deserialize an incompatible instance of the class, then yes, you should definitely update the serialVersionUID". This is a circular argument. It is only changing the `serialVersionUID` that *makes* the instance incompatible. Just adding a field won't do that. – user207421 Dec 12 '12 at 00:49
  • @EJP the link you shared in your answer discusses "incompatible changes" which are changes that affect the contract between the class and its callers, such that interoperability cannot be maintained. That's what I was referring to by "incompatible." – rob Dec 12 '12 at 02:16
  • 1
    The idea is to avoid those altogether rather than institute a policy of blithely incrementing `serialVersionUIDs`. They are pretty drastic: field type changes, inheritance hierarchy changes, class/package name changes, and they are all avoidable once you know the constraints. As I said in my answer, 'changing the actual `serialVersionUID` is a last resort, a counsel of despair'. – user207421 Dec 12 '12 at 03:08
  • But if you knowingly and intentionally make an incompatible change, should you not also change the serialVersionUID? It seems to me that it would be a bad idea to give the impression that the class is still compatible if compatibility is not guaranteed. – rob Dec 12 '12 at 18:08
  • @rob I don't know why you would ever do such a thing. If you go outside the bounds of the built-in versioning you should then take one or more of the measures mentioned in my answer so that serialization compatibility is preserved. – user207421 Jan 30 '13 at 23:04
  • @EJP your experience may differ from mine, but sometimes the spec for a major change doesn't require serialization compatibility. – rob Jan 30 '13 at 23:57