What changes if you make the previously non-serializable superclass implement Serializable too?
answer
- Parent Serializable -> its fields saved & restored automatically
- No-arg ctor no longer required
- Parent constructor now SKIPPED on deserialize
- Take on serialVersionUID + compatibility + transient
- Cleanest fix when you own the parent
basics
~20 sOnce the parent also implements Serializable, its fields get written to and restored from the stream like the child's. Java no longer needs to call the parent's no-arg constructor, so that constructor is no longer required and the parent's constructors are skipped during deserialization.
solid answer
~40 sIf the superclass also implements Serializable, it joins the serializable part of the hierarchy. Its declared fields are now written to the stream on serialization and restored directly on deserialization, so inherited state survives a round-trip automatically. The special handling for non-serializable ancestors no longer applies: Java does not call the parent's no-arg constructor, the parent's constructors are skipped (like all serializable classes), and there is therefore no requirement for the parent to have an accessible no-arg constructor. The trade-off is that you have now committed the parent to the serialization contract: its fields become part of the serialized form, you should give it a serialVersionUID, and changing it later can break compatibility. Making the parent Serializable is the simplest fix when you own the parent and actually want its state preserved.
go deeper
Understands that if the parent also implements Serializable, its fields are now saved and restored automatically.
Adds that the no-arg constructor is no longer required and the parent's constructor is skipped on deserialization.
Discusses the new obligations - serialVersionUID, transient, serialized-form stability, security - and when this fix is appropriate versus alternatives.
Frames making a class Serializable as a long-lived public-contract decision, considering versioning strategy, attack surface, and whether native serialization should be used at all.
## Recap of the non-serializable case When a Serializable subclass extends a **non-serializable** parent: the parent's fields are NOT written; on deserialization Java rebuilds the parent by calling its **no-arg constructor** (which must exist and be accessible); inherited state is lost (reset to constructor defaults). ## What flips when the parent implements Serializable Make the parent `implements Serializable`: ```java class Animal implements Serializable { // now Serializable String species; } class Dog extends Animal implements Serializable { String name; } ``` Now the entire chain is serializable, so: 1. **Parent fields are serialized.** `species` is written to the stream alongside `name`. On deserialization both are restored directly from the stream — **inherited state now survives** the round-trip automatically. No custom `writeObject`/`readObject` needed. 2. **Parent's no-arg constructor is no longer called.** Because the parent is part of the serializable region, deserialization does NOT invoke its constructor. Its fields come from the stream instead. 3. **The no-arg constructor requirement disappears.** Since Java no longer needs to call it, the parent can have only parameterized constructors (or a private one) and deserialization still works. (A subclass with `implements Serializable` doesn't strictly need a Serializable parent to have a no-arg ctor anymore.) 4. **Parent constructor side effects no longer fire on deserialize.** If the parent's constructor logged or registered something, that will stop happening during deserialization — which may be desirable or a subtle behavior change. ## New responsibilities you take on Making a class Serializable is a real API commitment: - **serialVersionUID**: declare `private static final long serialVersionUID = 1L;` on the parent so that class evolution doesn't cause `InvalidClassException` from auto-computed IDs changing. - **Serialized form stability**: the parent's fields are now part of its persisted/transmitted form; renaming or retyping them can break old data. Use `transient` for fields you don't want serialized (caches, derived values, secrets). - **Security**: every serializable field is an attack surface for crafted streams; validate in `readObject` if invariants matter. ## When to do it Making the parent Serializable is the **cleanest fix** to "my inherited state is being lost" — *if you own the parent and genuinely want that state preserved*. If you do NOT own the parent, can't modify it, or want to keep it serialization-free, the alternatives are: add an accessible no-arg constructor and manually preserve fields via the subclass's `writeObject`/`readObject`, or step away from Java serialization (DTO/JSON). ## One-line summary Making the parent Serializable moves it into the serializable region: its fields are saved and restored automatically, its constructor is skipped, and the no-arg-constructor requirement vanishes — at the cost of owning the parent's serialized form (serialVersionUID, compatibility, security).
- After making the parent Serializable, does it still need an accessible no-arg constructor for deserialization?No. The parent is now in the serializable region, so its constructor is skipped and the no-arg requirement no longer applies.
- What should you add to a class when you make it Serializable, and how do you exclude a field from serialization?Add an explicit serialVersionUID for version control. Mark fields you don't want serialized (caches, secrets, derived data) as transient so they are excluded and restored to defaults.
saying these in an interview costs you the question
- Thinking you still need the parent's no-arg constructor after making it Serializable
- Expecting the parent's constructor to keep running on deserialize
- Ignoring serialVersionUID once a class becomes Serializable
- Believing it has no downside (it commits you to the serialized form)