Java serialization: readObject() vs. readResolve()
The readObject()
method customizes deserialization by restoring an object's state from an input stream:
Meanwhile, readResolve()
manipulates post-deserialization outcomes like preserving singletons by switching the deserialized object with another:
Simply put, readObject()
dictates the how of deserialization, readResolve()
controls the what after deserialization.
Usage scenarios for readResolve
The readResolve()
can be useful when you must meet post-deserialization requirements like enforcing singleton pattern or maintaining immutable properties. When dealing with a singleton class, a new instance gets created during deserialization. Implementing readResolve()
can help replace the deserialized object with the singleton instance:
For an immutable property, readResolve()
can be used to maintain its state during deserialization, even when they have final fields.
Working with readObject and readResolve
- Duplicate elimination: Use
readResolve()
to compare a deserialized object with a pre-existing instance registry to replace duplicates. - Consistency assurance: In distributed systems,
readResolve()
can update object references for synchronized versions across multiple nodes. - Custom object initialization: Fields not serialized can be initialized consistently by using APIs like xstream and
readResolve()
.
Serialization proxies explained
As introduced in Effective Java, the serialization proxy pattern uses writeReplace
to serialize a separate object that encapsulates the logical state. During deserialization, readResolve()
converts this proxy back to the original object thus providing a safer technique for the serialization process.
Dive into readResolve
- Type variety: The return type of
readResolve()
can be of the same type or even a different class, depending on what you want to substitute the deserialized object with. - Execution timeline:
readResolve()
is called before deserialization, letting you replace the deserialized object.
Common pitfalls
- Misuse of readResolve: Unnecessary use of
readResolve()
might complicate your code. - Overriding variables: Beware of
readResolve()
unintentionally overriding final variables. - Security issues: Be mindful about potentially harmful payloads exploiting the
readObject()
orreadResolve()
methods.
Was this article helpful?