【问题标题】:How to ensure consistency of enums in Java serialization?Java序列化中如何保证枚举的一致性?
【发布时间】:2010-06-16 22:54:38
【问题描述】:

当我序列化一个对象时,我可以在类级别使用serialVersionUID机制来保证两种类型的兼容性。

但是,当我序列化枚举值的字段时会发生什么?有没有办法确保枚举类型在序列化和反序列化之间没有被操纵?

假设我有一个像 OperationResult {SUCCESS, FAIL} 这样的枚举,并且在一个正在序列化的对象中有一个名为“result”的字段。我如何确保在反序列化对象时,即使有人恶意颠倒了两者,结果仍然正确? (假设枚举在别处声明为静态枚举)

出于好奇,我想知道 - 我使用 jar 级身份验证来防止操纵。

【问题讨论】:

    标签: java serialization enums


    【解决方案1】:

    发件人:http://www.theserverside.com/news/thread.tss?thread_id=50190#265205

    枚举功能的设计者决定 没有用例来创建新的 在运行时枚举对象。他们拿了 非常小心,不允许这样做。

    因此,看起来枚举对象无法整体序列化和反序列化。另外,来自http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469

    枚举常量被序列化 不同于普通的可序列化 或可外化的对象。这 枚举常量的序列化形式 仅由其名称组成;场地 常量的值不存在 在表格中。序列化枚举 常量,ObjectOutputStream 写入 枚举返回的值 常量的命名方法。反序列化 一个枚举常量,ObjectInputStream 从 溪流;反序列化的常数是 然后通过调用 java.lang.Enum.valueOf 方法,通过 常量的枚举类型以及 收到的常量名称为 论据。像其他可序列化或 可外部化的对象,枚举常量 可以作为背部的目标 随后出现的参考文献 序列化流。

    枚举常量的过程 被序列化不能自定义: 任何特定于类的 writeObject, 读取对象,读取对象无数据, writeReplace 和 readResolve 方法 由枚举类型定义的被忽略 在序列化和 反序列化。同样,任何 serialPersistentFields 或 serialVersionUID 字段声明 也被忽略——所有枚举类型都有 0L 的固定 serialVersionUID。 记录可序列化的字段和 枚举类型的数据是不必要的, 因为没有变化 发送的数据类型。

    【讨论】:

      【解决方案2】:

      枚举在反序列化期间被读取替换。引用 1.5 版的 serialization release notes

      序列化枚举的规则 实例不同于那些 序列化一个“普通的”可序列化的 对象:枚举的序列化形式 实例仅包含其枚举 常量名称以及信息 识别其基本枚举类型。 反序列化行为不同为 好吧——类信息用于 找到合适的枚举类,并且 调用 Enum.valueOf 方法 该类和接收到的常量 名称以获取枚举 常量返回。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-02
        • 2013-08-24
        • 2014-08-10
        • 2013-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多