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?
