Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当类/代码签名更改时,是否有方法自动重新生成serialVersionId?_Java_Serialization - Fatal编程技术网

Java 当类/代码签名更改时,是否有方法自动重新生成serialVersionId?

Java 当类/代码签名更改时,是否有方法自动重新生成serialVersionId?,java,serialization,Java,Serialization,我们有一大堆序列化的类,但希望数据库位在“签名”即:类的字段结构和序列化代码更改时失效 是否有一个实用程序可以为类文件生成一个“哈希”,以便在该类的java.serializable的序列化结构发生更改时进行最佳检测?由于一个相当重要的原因,实际上无法“在序列化结构发生更改时进行最佳检测”: 序列化破坏了封装 实现可序列化的时,类的所有私有字段和包私有字段以及成员都将成为该类导出API的一部分。从类发布到野外的那一刻起,其序列化形式(包含其所有实现细节)就是其契约的一部分。更改序列化表单将产生以

我们有一大堆序列化的类,但希望数据库位在“签名”即:类的字段结构和序列化代码更改时失效

是否有一个实用程序可以为类文件生成一个“哈希”,以便在该类的java.serializable的序列化结构发生更改时进行最佳检测?

由于一个相当重要的原因,实际上无法“在序列化结构发生更改时进行最佳检测”:

序列化破坏了封装

实现可序列化的
时,类的所有私有字段和包私有字段以及成员都将成为该类导出API的一部分。从类发布到野外的那一刻起,其序列化形式(包含其所有实现细节)就是其契约的一部分。更改序列化表单将产生以下两种后果之一:

  • 向后兼容性。因为
    Serializable
    破坏了封装,所以序列化表单成为其导出API的一部分。当实现细节发生更改时,开发人员可自行决定定制的
    readObject()
    writeObject()
    方法可设计为继续支持原始序列化表单(即使新实现会导致表单更改)。如果API非常广泛,并且更改序列化形式会破坏API的许多客户机,那么这是可取的。在这种情况下,即使新实现会更改序列化表单,serialVersionUID也需要保持不变才能继续支持原始序列化表单

  • 强制升级。如果类的实现发生更改,并且不可能或不可行支持原始序列化表单,则更改serialVersionUID将导致API的客户端中断,从而强制升级客户端以使用新的序列化表单。这在某些情况下可能是可取的(但会迫使客户端升级其代码)

值得一提的是,如果您没有在可序列化类中显式声明静态最终serialVersionUID,Java环境将通过对代码应用复杂过程(考虑字段和方法签名)自动为您计算一个serialVersionUID


简而言之,serialVersionUID应该跟踪所使用的序列化表单,而不是实际的类实现。如果希望每当类实现更改时serialVersionUID自动更改,只需省略serialVersionUID的显式声明(但这可能会产生其他负面后果)。更改serialVersionUID的决定需要明确地根据您希望API在实现细节更改时的行为做出。

如果您使用eclipse,您可以让eclipse为您生成一个新id。为什么?这只意味着你必须扔掉旧数据。你应该尽最大努力保存它。您需要仔细阅读对象序列化规范的版本控制章节。在保留序列化兼容性的同时,可以对类执行很多操作。比人们普遍认为的要多。您应该限制您的更改以适应该框架。您从错误的角度看待这个问题。@EJP普通序列化(没有代理和其他技巧)对于快速发展的系统中的长期存储几乎毫无用处。因此,这很可能是一个合理的问题。话虽如此,扔掉所有遗留数据并没有任何好处。:)@biziclop被大大夸大了,无论如何,这就是OP想要做的。他的提议将使情况变得更糟。这根本不是一个“有效问题”。@EJP可能是。不管怎样,这听起来有点像一个X-Y问题。另请参阅,以获取有关如何避免Java序列化的许多问题的解决方案。我同意-为什么我的问题:)对于我们来说,这是在开发过程中,这将是一个非常好的问题,因此我们可以自动使开发数据库的部分无效。我知道ID生成器必须查看编译的结果和所有超类,看看从serializable调用的代码是否已更改,或者它引用的数据(类的结构)是否已更改,并将其与当前值进行比较。这就是说,如果有一个工作,它将是凉爽和方便。