当我序列化一个对象时,我可以在类级别使用serialVersionUID机制来确保这两种类型的兼容性。
但是,当我序列化枚举值字段时会发生什么?有没有办法确保序列化和反序列化之间没有操作枚举类型?
假设我有一个类似OperationResult {SUCCESS,FAIL}的枚举,以及一个被序列化的对象中名为“result”的字段。当对象被反序列化时,即使有人恶意颠倒了这两个结果,我如何确保结果仍然正确? (假设枚举在其他地方声明为静态枚举)
我想知道好奇心 - 我使用jar级别的身份验证来防止操纵。
答案 0 :(得分:22)
来自:http://www.theserverside.com/news/thread.tss?thread_id=50190#265205
枚举功能的设计者决定了 创建新的没有用例 在运行时枚举对象。他们接受了 非常小心,不允许它。
因此,看起来enum对象无法完整地序列化和反序列化。另外,来自http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469:
枚举常量被序列化 与普通的可序列化不同 或可外部化的对象。该 枚举常量的序列化形式 仅由其名称组成;领域 常数的值不存在 在形式。序列化枚举 常量,ObjectOutputStream写入 枚举返回的值 常量的名称方法。反序列化 枚举常量,ObjectInputStream 从中读取常量名称 流;反序列化的常量是 然后通过调用获得 java.lang.Enum.valueOf方法,传递 常量的枚举类型 收到的常量名称为 参数。像其他可序列化或 可外化对象,枚举常量 可以作为背部的目标 随后出现的参考文献 序列化流。
枚举常量的过程 序列化无法定制: 任何特定于类的writeObject, readObject,readObjectNoData, writeReplace和readResolve方法 由枚举类型定义的内容将被忽略 在序列化和 反序列化。同样,任何 serialPersistentFields或 serialVersionUID字段声明 也被忽略 - 所有枚举类型都有 固定的serialVersionUID为0L。 记录可序列化的字段和 枚举类型的数据是不必要的, 因为没有变化 发送的数据类型。
答案 1 :(得分:5)
在反序列化期间读取枚举的枚举。引用版本1.5的serialization release notes:
序列化枚举的规则 实例不同于 序列化“普通”可序列化 object:枚举的序列化形式 实例仅包含其枚举 常数名称,以及信息 识别其基本枚举类型。 反序列化行为有所不同 好吧 - 班级信息习惯了 找到合适的枚举类,和 使用调用Enum.valueOf方法 那个班级和收到的常数 name以获取枚举 不断返回。