views:

63

answers:

2

When I serialize an object, I can use the serialVersionUID mechanism at the class level to ensure the compatibility of the two types.

However, what happens when I serialize fields of enum values? Is there a way to ensure that the enum type has not been manipulated between serialization and deserialization?

Suppose that I have an enum like OperationResult {SUCCESS, FAIL}, and a field called "result" in an object that is being serialized. How do I ensure, when the object is deserialized, that result is still correct even if someone maliciously reversed the two? (Suppose the enum is declared elsewhere as a static enum)

I am wondering out of curiosity - I use jar-level authentication to prevent manipulation.

+2  A: 

Enums are read-replaced during deserialization. Quoting the serialization release notes for version 1.5:

The rules for serializing an enum instance differ from those for serializing an "ordinary" serializable object: the serialized form of an enum instance consists only of its enum constant name, along with information identifying its base enum type. Deserialization behavior differs as well--the class information is used to find the appropriate enum class, and the Enum.valueOf method is called with that class and the received constant name in order to obtain the enum constant to return.

meriton
+5  A: 

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

The designers of enum feature decided there is no use case to create new enum objects at runtime. They took great care to not allow it.

Therefore, it looks like enum objects cannot be serialised and deserialised in their entirety. Also, from http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469:

Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant's enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream.

The process by which enum constants are serialized cannot be customized: any class-specific writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods defined by enum types are ignored during serialization and deserialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L. Documenting serializable fields and data for enum types is unnecessary, since there is no variation in the type of data sent.

Chris Dennett