为什么依赖 ObjectStreamClass.getSerialVersionUID 是不安全的?

why is not safe to rely on ObjectStreamClass.getSerialVersionUID?

java 规范说:"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"

有人可以深入研究一下吗? getSerialVersionUID()方法是做反射的,到处都用到反射,那什么是compiler-dependent呢?

J. Bloch 的书 "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:评论里也有人问我,为什么是compiler-dependent。实际上,这里的编译器依赖性与 getSerialVersionUID() 算法本身无关(方法在运行时调用,当然),而是 class 本身的描述方式。比如一些合成方法可以在编译时添加到class中,这些方法也会被计算在SUID中。有关详细信息,请查看方法 ObjectStreamClass.computeDefaultSUID()、它的作用以及如何计算默认 SUID。