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?