Java serialization: readObject() vs. readResolve()
readObject()
is an existing method in ObjectInputStream
class.
At the time of deserialization readObject()
method internally checks whether the object that is being deserialized has readResolve()
method implemented. If readResolve()
method exists then it will be invoked
A sample readResolve()
implementation would look like this
protected Object readResolve() {
return INSTANCE:
}
So, the intent of writing readResolve()
method is to ensure that the same object that lives in JVM is returned instead of creating new object during deserialization.
readResolve can be used to change the data that is serialized through readObject method. For e.g. xstream API uses this feature to initialize some attributes that were not in the XML to be deserialized.
http://x-stream.github.io/faq.html#Serialization
readResolve
is used for replacing the object read from the stream. The only use I've ever seen for this is enforcing singletons; when an object is read, replace it with the singleton instance. This ensures that nobody can create another instance by serializing and deserializing the singleton.
Item 90, Effective Java, 3rd Ed covers readResolve
and writeReplace
for serial proxies - their main use. The examples do not write out readObject
and writeObject
methods because they are using default serialisation to read and write fields.
readResolve
is called after readObject
has returned (conversely writeReplace
is called before writeObject
and probably on a different object). The object the method returns replaces this
object returned to the user of ObjectInputStream.readObject
and any further back references to the object in the stream. Both readResolve
and writeReplace
may return objects of the same or different types. Returning the same type is useful in some cases where fields must be final
and either backward compatibility is required or values must copied and/or validated.
Use of readResolve
does not enforce the singleton property.