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

Uri*_*Uri 16 java enums serialization

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

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

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

我出于好奇而想知道 - 我使用jar级别的身份验证来防止操纵.

Chr*_*ett 22

来自: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,readObject,readObjectNoData,writeReplace和readResolve方法.同样,任何serialPersistentFields或serialVersionUID字段声明也会被忽略 - 所有枚举类型都有一个固定的serialVersionUID为0L.记录枚举类型的可序列化字段和数据是不必要的,因为发送的数据类型没有变化.


mer*_*ike 5

在反序列化期间读取枚举的枚举.引用1.5版的序列化发行说明:

序列化枚举实例的规则与序列化"普通"可序列化对象的规则不同:枚举实例的序列化形式仅包含其枚举常量名称,以及标识其基本枚举类型的信息.反序列化行为也有所不同 - 类信息用于查找适当的枚举类,并使用该类和接收的常量名称调用Enum.valueOf方法,以获取要返回的枚举常量.