问题
I have an enum JJJ that has 3 values: A, B, and C. In previous versions of my program it had one additional value: D. I'd like to be able to read in the serialized objects created by previous versions of the program, but an exception is thrown when it encounters a JJJ type variable with value 'D' in the serialized object. Optimally, I'd like to be able to intercept the deserialization process and tell it to just map D's to C's when it encounters them.
According to http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html (Serialization of Enum Constants), it doesn't sound like there is a simple way to do this... I know that one approach would be to override readObject on the classes that contain member variables of type JJJ, but this would be difficult and painful due to the size and scope of the program (dozens of serializable classes have member vars of type JJJ and overriding readObject to handle the JJJ field means I'd have to manually handle all of the other fields as well).
I've also attempted to solve this by rolling my own subclass of ObjectInputStream, but unfortunately the enum deserialization bits I really need to get at and override to solve this are all private or package private...
Any suggestions?
回答1:
I haven't actually tried this, but perhaps it could work:
Create a new class "oldClass" with exactly the same fields as the old one.
Extend ObjectInputStream in the way this post describes so that you deserialize in an instance of "oldClass".
In that "oldClass" you have created, implement "readResolve()", so that you return a instance of the new version of your class, changing the missing fields as you like.
回答2:
FYI, for any other poor souls out there trying to handle this case, this is the solution I ended up implementing:
I created a special interface for enums that looks like this:
public interface SerialCompatEnum {
public String convertOldValue(String oldValue);
}
I then wrote a class that takes an raw serialized java object byte stream as input, processes it, and writes a modified version of the byte stream to an arbitrary output stream. The processing logic picks up any enum instances in the serialized byte stream and uses the convertOldValue method to replace the enum constant in the stream with an updated string that actually exists in the current code base. We run all of our serialized object through this processor first to prevent total failures caused by missing enum constants.
Unfortunately, not a very clean or easy solution. :/
来源:https://stackoverflow.com/questions/8743668/handling-deserialization-of-enum-values-that-no-longer-exist