Java.Serialization.What are the ways to control the values ​​of the deserialized object

🔧 1. Use a Custom readObject() Method

This is the standard way to hook into deserialization:

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject(); // Restore default values

    // 💡 Customize here
    if (age < 0) age = 0; // Validation
    if (nickname == null) nickname = "Anonymous";
}

🔍 What this gives you:

  • Access to the object’s fields right after they’re deserialized
  • The ability to change, correct, or fill in missing/transient data

🔐 2. Use readResolve() to Replace the Object

This is great for:

  • Singletons
  • Immutable instances
  • Object deduplication
private Object readResolve() throws ObjectStreamException {
    // Replace the deserialized object with a canonical one
    return MyObjectRegistry.getInstanceById(this.id);
}

➕ Bonus:

  • You can return a completely different object than the one Java just built

🧪 3. Use transient + Reinitialization Logic

Fields marked as transient are skipped during serialization. You can:

  • Add default values in readObject()
  • Recalculate them using other deserialized fields
transient String cache;

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    this.cache = this.name.toUpperCase(); // Restore derived field
}

🛡 4. Validate Object with ObjectInputValidation (less common)

This is a special hook for post-processing:

in.registerValidation(obj -> {
    if (obj.age < 0) throw new InvalidObjectException("Invalid age!");
}, 0);

✅ Used for deep validation or dependency-based checks.

⚠️ 5. Constructor Does Not Run During Deserialization!

Remember:

  • Java bypasses constructors during deserialization using ReflectionFactory
  • So if you rely on constructor logic (e.g., init defaults), you need to repeat it in readObject()

🧵 TL;DR — How to Control Values on Deserialization

MethodWhat It ControlsWhen to Use
readObject()Modify, validate, reinitialize fieldsMost flexible and common
readResolve()Replace the whole objectFor Singletons, canonical forms
transient + reinitSkip field + restore manuallyDerived/cached/volatile data
ObjectInputValidationValidate after full object graph is readAdvanced validation logic
This entry was posted in Без рубрики. Bookmark the permalink.

Leave a Reply

Your email address will not be published.