Details
-
Type: New Feature
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.0.1
-
Component/s: Converters
-
Labels:None
Description
------- From Chris Kelly ---------
Normally for serializable enums, then you have a readResolve method so that at you can still use the == operator after deserialization as the local static constant replaces the deserialized one. However when I de-serialize a typesafe enum using XStream then the constants refer to differnt objects thus removing the benefit of using a typesafe constant in the first place. Is this a bug or am I misusing XStream?
[I enclose a typical typesafe constant with unit tests for normal serialization and serialization using XStream)]
Thanks for any suggestions in advance.
public class Status implements Serializable, Comparable {
private static int nextOrdinal = 0;
private final int ordinal = nextOrdinal++;
public static final Status STARTED = new Status("STARTED");
public static final Status FINISHED = new Status("FINISHED");
private static final Status[] PRIVATE_VALUES =
;
public static final List VALUES = Collections.unmodifiableList(
Arrays.asList(PRIVATE_VALUES));
private final String name; // for debug only
static final long serialVersionUID = 4931026467582637777L;
private Status(String name)
{ this.name = name; }public String toString()
{ return name; }public int compareTo(Object o)
{ return ordinal - ((Status) o).ordinal; }private Object readResolve() throws ObjectStreamException
{ return PRIVATE_VALUES[ordinal]; //Canonicalize }}
public void testReadResolveWithDefaultSerialization() {
Status status = Status.STARTED;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
catch (Exception e)
{ fail("Unable to serialize", e); } byte[] bArray = bout.toByteArray();
Status rStatus = null;
ObjectInputStream in = null;
ByteArrayInputStream bin = new ByteArrayInputStream(bArray);
try
{ in = new ObjectInputStream(bin); rStatus = (Status) in.readObject(); assertNotNull(rStatus); }catch (Throwable t)
{ fail("Unable to read de-serialize", t); } assertSame(status, rStatus);
}
public void testReadResolveWithXStream()
{ Status status = Status.STARTED; XStream xstream = new XStream(); xstream.registerConverter(new EncodedByteArrayConverter()); String xml = xstream.toXML(status); Status rStatus = (Status)xstream.fromXML(xml); assertSame(status, rStatus); }----------- Extra Joe notes --------
This should be easy to implement. ReflectionConverter can check for the existence of the method and if so, return that instead. Might cause an issue with circular references.