Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 2
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException{
try{
_fieldName=(String)in.readObject();
}catch(ClassNotFoundException ex){
throw new java.io.IOException(ex.getMessage());
}
}
The readResolve() method then identifies the object's local static instance (by matching on the _fieldName field) and returns the corresponding object. The net result is that you can still use the == operator after deserialization because the local static constant replaces the deserialized one:
public Object readResolve()
throws java.io.ObjectStreamException{
try{
Class clazz=getClass();
Field f=clazz.getField(_fieldName);
return f.get(null);
}catch(Exception ex){
ex.printStackTrace();
throw new java.io.InvalidObjectException(
"Failed to resolve object");
}
}
}
One important point about the writeObject() method is that only a matching public static final field name is written to the stream; any additional state is ignored. So what happens when a constant has an additional state
as shown below?
public final class NumberConstants extends AbstractConstant{
public static final NumberConstants ONE=new NumberConstants("1");
//etc
public String toString(){
return _rep;
}
private final String _rep;
private NumberConstants(String rep){
_rep=rep;
}
}
We are dealing with static constants, so any additional state appears preserved because readResolve() matches the constant's serialized representation with the local object reference. If for any reason a program changes state
associated with a constant (i.e., a field isn't declared final) between serializing and deserializing, then this technique fails. However, changing state associated with a constant means
it's not a constant after all, and you probably shouldn't apply this idiom in the first place.
Assuming you use typesafe constants in their canonical form, you can simply extend the AbstractConstant class and happily write and use typesafe constants knowing they will work with serialization.
This technique also works with Jini entries (that have different serialization semantics) and therefore with JavaSpaces, where
a key field in an Entry is an instance of a class that extends the AbstractConstant.
Finally, keep in mind that this solution applies to simple serialization and works with many distributed Java systems, but it does not address the multiple classloader problems identified in Roubtsov's article.