2

I have implemented Serializable objects in my android app to keep backward compatibility.

Sadly i created my classes like this:

Class Foo implements Serializable {
   private static long serialVersionUID = 928374172L;
   [...]
}

As i painfully figured out, Java doesn't recognize this value as the serialVersionUID because the "final" statement is missing.

The problem is i can't create the private static final long serialVersionUID because there is already an object named like this... :/

Is there any chance to save this class or do i have to create a Foo2 class and copy all saved data into it? Maybe any better way? Because i have to modify this class without loosing all saved data.

Prexx
  • 2,959
  • 5
  • 31
  • 48
  • Why is renaming the other variable feasible? – npinti Aug 14 '15 at 12:45
  • You don't need serialVersionUID unless you modify the class that you used to serialise your objects. You can simply de serialise them. This field is useful if you modify the class after serialising and then during de serialisation of objects to current version you will know that the class is changed. –  Aug 14 '15 at 12:47
  • You mean you need to keep backward compatibility with data that has been serialized on devices where the app is already deployed? – dotvav Aug 14 '15 at 12:48
  • @amitmahajan Because i need to modify the class without loosing all saved data.. :( – Prexx Aug 14 '15 at 12:48

2 Answers2

3

Your current serialVersionUID is static, so it does not participate in the (de)serialization of the objects. So it is safe to add final to it.

If your current value is not the default one already, change it, as described here and here.

Community
  • 1
  • 1
Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
  • However that will break all existing seialziations, which were made with the default value. – user207421 Aug 14 '15 at 12:54
  • I assume that the OP will change the value to the default one. I understood the question was about the inability to define `serialVersionUID` for that class any longer. – Dragan Bozanovic Aug 14 '15 at 12:56
  • 1
    It isn't 'safe to add `final` to it' *unless* he *also* fixes the value. Assuming isn't stating. – user207421 Aug 14 '15 at 12:59
  • I just want to define a serialVersionUID so that i can modify that class without getting exceptions while deserialization. However, your tip worked. I just changed 'private static long serialVersionUID=xy' to 'private static final long serialVersionUID=xy'. I got an exception that the deserialization failed because of incompatible classes. In this exception there is the current versionUID printed. I took that instead of 'xy' and it worked. Thanks! :) – Prexx Aug 14 '15 at 13:00
  • Prexx, You're welcome. @EJP, thanks for the remark, I edited my answer by providing more details. – Dragan Bozanovic Aug 14 '15 at 13:03
  • I tried this way before. I just copied the wrong value printed in the exception. The trick is to copy the first one. I think the exception text is a bit misleading: "Deserialization of object failed!; Incompatible class (SUID): : static final long serialVersionUID =3502031867290706386L; (<-TAKE THIS ONE) but expected : static final long serialVersionUID =981248231L;" – Prexx Aug 14 '15 at 13:11
1

You need to do two things.

  1. Run the serialver tool on the class as it is right now. That gives you the value, indeed the entire statement, that was assumed when existing serializations were made.
  2. Replace the existing statement with what the tool gave you, including the keyword final. That won't break anything, but it will future-proof the class against breaking when you do Serialization-compatible changes to it, as outlined in the Versioning chapter of the Object Serialization Specification.
user207421
  • 305,947
  • 44
  • 307
  • 483