serializable - is there a built-in way to detect if a serialized java object is missing fields? -
i'm making compatible modifications serializable class, namely adding few primitive fields (boolean, long). class client-side representation of data provided server.
when load class file, need able detect if loaded class saved earlier version, i.e. missing fields java set default value on load. if case, app still work, when client has network connectivity, i'd fetch new fields server.
does java have built-in methods detect if class missing fields loaded?
(i realize can solve manually "version" instance member; hoping though java has built-in)
you can override readobject() method of serializable interface custom handle deserialization of class.
note strongly recommended include serialversionuid whenever implement serializable:
private static final long serialversionuid = 1;
if don't define it, 1 created hash of class's members... if later add things describe, uid won't match , java won't let reload old data.
more info serializable docs here: http://docs.oracle.com/javase/6/docs/api/java/io/serializable.html
futher information on handling non-breaking changes:
you should ever change serialversionuid if there breaking changes between implementations make nonsensical deserialize old version new code.
if modify class non-breaking changes adding fields, shouldn't change serialversionuid. if original class had no specified serialversionuid, 1 auto-generated you, , new 1 autogenerated in new implementation doesn't match old one.
when try deserialize old version serialversionuid mismatch, system throw java.io.invalidclassexception. error message exception tell old serialversionuid , new 1 is.
you can modify class have explicitly specified serialversionuid matches old version, allowing deserialize old versions , new without exceptions being thrown.
the run-time set new primitive members default values when deserializing old version instance.
if want detect whether you've deserialized old version of class or new one, can check default value shouldn't default in readobject() implementation.
here's example:
// add new private field modified class tracking version: private int mynewversionflag = 123; // in readobject implementation: private void readobject(java.io.objectinputstream stream) throws ioexception, classnotfoundexception { stream.defaultreadobject(); if( this.mynewversionflag == 0 ) { // if here object being deserialized must // old version, set sensible defaults // new params or whatever... } }
there other more sophisticated approaches including implementing own subclass of objectinputstream, in general, find having version field shouldn't 0 simple , sufficient many use-cases.
summary
if specify own serialversionuid code more efficient (it doesn't have auto-generate hashed one) , better able handle future class changes explicitly.
you should change value if changes breaking , mean deserializing old version of class impossible due no sensible defaults being possible new features of class.
if have own private member tracking version numbers can use within readobject() insert sensible defaults new variables when deserializing old instances if need to.
finally, ever wanted know deserialization (but afraid ask) covered in java serialization specification:
http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serialtoc.html
Comments
Post a Comment