2

The java spec says: "it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations"

Please could someone dig into this? The getSerialVersionUID() method does reflection, and reflection is used commonly everywhere, so what is compiler-dependent?

ejaenv
  • 2,117
  • 1
  • 23
  • 28

1 Answers1

2

Brilliant explanation of this question is given in J. Bloch book "Effective Java":

"Item 74: Implement Serializable judiciously":

If you do not specify this number explicitly by declaring a static final long field named serialVersionUID, the system automatically generates it at runtime by applying a complex procedure to the class. The automatically generated value is affected by the class’s name, the names of the interfaces it implements, and all of its public and protected members. If you change any of these things in any way, for example, by adding a trivial convenience method, the automatically generated serial version UID changes

UPD: I was also asked in commentary, why it is compiler-dependent. Actually compiler-dependency here is not about getSerialVersionUID() algorithm itself (method is invoked in runtime, sure), but it is in how class is described itself. For instance some synthetic methods can be added into the class at compile time, which will be counted in SUID as well. For details, look at method ObjectStreamClass.computeDefaultSUID(), what it does and how computes default SUID.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
  • but this explanation doesn't say why is compiler-dependent. Is getSerialVersionUID() used in realtime to calculate the value? – ejaenv Dec 07 '16 at 15:15
  • @ejaenv, look at my upd – Andremoniy Dec 07 '16 at 15:30
  • 1
    Even without compiler dependencies, you don’t want to use an algorithm that considers the persistent form incompatible, when you change `static` fields or *methods*. Even whether the class has an initializer has an impact. What the quote text fails to mention is that not only “*all of its public and protected members*”, but also all package-private members are accounted, which is why synthetic methods like inner class accessors matter… – Holger Dec 07 '16 at 17:30
  • IMO computeDefaultSUID should be changed for one useful. – ejaenv Dec 07 '16 at 19:14
  • @ejaenv: well, changing the algorithm would break compatibility with all existing serialized data and also imply that data stored using the new algorithm will be rejected by older JREs. – Holger Dec 08 '16 at 12:29