【问题标题】:Why jvm generates serialVersionUID? [duplicate]为什么jvm会生成serialVersionUID? [复制]
【发布时间】:2014-09-12 11:26:19
【问题描述】:

根据docs

序列化运行时将一个版本号与每个可序列化类相关联,称为 serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。

如果serialVersionUID只是为了验证一个序列化对象的发送者和接收者是否已经加载了该对象的类,那么jvm不能使用类名本身进行验证。

【问题讨论】:

    标签: java jakarta-ee


    【解决方案1】:

    你错过了引用的后半部分:

    在序列化方面兼容

    如果您想拥有序列化类对象的多个“版本”,您需要一个可以更改的标识符。你不能只通过类名来做到这一点。

    打个比方,这有点像说为什么我们需要传入HTTP版本(HTTP/1.1),因为它最终是HTTP。这取决于协议“版本”以及协议本身。

    【讨论】:

    • Doc 声明“serialVersionUID”必须是 staticfinal 和 long 类型(即类级常量)。那么就出现了改变标识符的问题。而且在运行时,加载的类名反正是唯一的,那jvm为什么不能用类名作为id,只要基本目的是验证序列化的发送方和接收方对象已为该对象加载 。当然,我错过了一些东西。
    • @cooper:想想一个不断发展的类/模式。您可以继续在班级中添加/删除字段。要跟踪这些更改,您可以不断增加版本 ID。发送序列化数据时,接收方会检查“版本”以及类类型;如果类类型匹配但版本不匹配,则反序列化不起作用。当您创建像 RMI 这样的服务时,这一点变得至关重要,其中序列化的类对象在客户端和服务器之间交换,并且客户端和服务器都处理相同的“逻辑”模式很重要。
    • True sir.Nice Usecase.JVM 在生成 UID 时考虑了类的所有成员,可能还有 jvmVersion 和 OS。但 DOC 没有声明/建议使用 UID 来跟踪对类结构所做的更改。它声明“强烈建议所有可序列化类显式声明 UID 值,因为默认 UID 计算对类细节高度敏感,可能因编译器实现而异”,似乎我们显式添加补丁.理论上通过UID跟踪类结构的演变是可以理解的,需要考虑到实际方便/可行的程度
    • @cooper:您质疑这些 id 的有用性是正确的。我在过去创建了 RMI 服务,但鉴于我们的客户端版本与服务器版本完美同步,所以从来没有需要弄乱版本 ID。我可以想象,如果您要公开大量第三方客户端使用的 RMI 服务,并且您必须绝对确保每个人都使用相同的类版本,那么这个概念可能会派上用场。所以是的,如果需要,它并不总是有用但很漂亮的功能。
    【解决方案2】:

    好吧,要了解 Serializable Class 的概念及其 serialVersionUID,最好阅读其完整的 java doc(java.io.Serializable),并通过适当的示例进行解释。

    您的问题似乎与this question. 重复 已就该主题进行了适当且成熟的讨论。希望这会有所帮助。

    【讨论】:

    • 先生,看起来讨论是关于“为什么要使用 SerialVersionUID”。如果您不介意,能否请您从成熟的讨论中复制准确回答我的问题的特定部分,即 Why jvm generate serialVersionUID ,而不是使用类名本身进行验证。
    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 2012-01-18
    • 2010-10-27
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多