我们有一大堆序列化类,但是每当"签名"时,都希望数据库位无效。即:类的字段结构和序列化代码更改,
是否有可以生成"哈希"的实用程序?对于一个类文件,它将最佳地检测java.serializable的序列化结构何时为该类更改?
答案 0 :(得分:3)
实际上没有办法最佳地检测序列化结构何时发生变化"出于一个相当重要的原因:
序列化打破了封装。
当您实施Serializable
时,所有私有和包私有字段以及类的成员都将成为该类导出的API的一部分。从一个类发布到野外的那一刻起,它的序列化形式(包含其所有实现细节)是其合同的一部分。更改序列化表单将产生以下两种后果之一:
向后兼容性。由于Serializable
打破了封装,序列化表单成为其导出API的一部分。当实施细节发生变化时,开发人员可自行决定定制readObject()
和writeObject()
方法以继续支持原始序列化形式(即使它会因新的形式而发生变化)实现)。如果API被广泛使用并且更改序列化形式会破坏API的许多客户端,这是可取的。在这种情况下,即使序列化表单会因新实现而改变,serialVersionUID也需要保持不变才能继续支持原始序列化表单。
强制升级。如果类的实现发生更改并且支持原始序列化表单是不可能或不可行的,则更改serialVersionUID将导致API的客户端中断,从而强制客户端升级以使用新的序列化表单。在某些情况下这可能是合乎需要的(但会迫使客户升级其代码)。
值得一提的是,如果您没有在可序列化类中显式声明静态最终serialVersionUID,那么Java环境将通过对代码应用复杂过程(考虑字段和方法签名)自动为您计算一个
简而言之,serialVersionUID应该使用所使用的序列化表单而不是实际的类实现。如果您希望在类实现发生更改时自动更改serialVersionUID,则可以简单地省略serialVersionUID的显式声明(但这可能会产生其他负面后果)。需要明确更改serialVersionUID的决定取决于您希望API在实现细节更改时的行为方式。