如何确保Java序列化中枚举的一致性?

时间:2010-06-16 22:54:39

标签: java serialization enums

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

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

假设我有一个类似OperationResult {SUCCESS,FAIL}的枚举,以及一​​个被序列化的对象中名为“result”的字段。当对象被反序列化时,即使有人恶意颠倒了这两个结果,我如何确保结果仍然正确? (假设枚举在其他地方声明为静态枚举)

我想知道好奇心 - 我使用jar级别的身份验证来防止操纵。

2 个答案:

答案 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以获取枚举   不断返回。