Can you inherit from an immutable class?
Technically — yes, if the class is not marked as final. But it's a bad idea, because a subclass can add mutable fields, and then code expecting an immutable object will get a mu...
Junior Level
Technically — yes, if the class is not marked as final. But it’s a bad idea, because a subclass can add mutable fields, and then code expecting an immutable object will get a mutable one.
Example of the problem
// "Immutable" class, but without final
public class ImmutableBase {
private final String value;
public ImmutableBase(String v) { this.value = v; }
public String getValue() { return value; }
}
// Subclass adds mutability
public class MutableChild extends ImmutableBase {
private String extra; // mutable field
public void setExtra(String e) { this.extra = e; }
}
Solution
Always declare immutable classes as final:
public final class ImmutablePoint { ... } // inheritance is impossible
Middle Level
Why inheritance breaks immutability
- New mutable fields — a subclass can add
private String extrawith a setter - Overriding methods — a subclass can override getters, returning different data
- Unstable hashCode — immutable objects often cache hashCode; a subclass with mutable fields makes this cache invalid.
Alternatives to inheritance
1. Composition instead of inheritance
public final class ExtendedPoint {
private final ImmutablePoint point;
private final String label;
// ...
}
2. Private constructors + static factories
public final class ImmutableObject {
private final String data;
private ImmutableObject(String data) { this.data = data; }
public static ImmutableObject of(String data) { return new ImmutableObject(data); }
}
Examples from JDK
All fundamental immutable classes are final: String, Integer, BigDecimal, LocalDate.
Senior Level
Polymorphism as a threat
If a method expects ImmutableBase and relies on its immutability (e.g., caches a result based on getValue()), substituting MutableChild can lead to:
- Invariant violation — data changes after validation
- Security bypass — subclass returns different data after validation
- Loss of thread-safety — subclass accesses non-
finalfields without synchronization
Sealed Classes (preview in Java 15, stable in Java 17)
If limited inheritance is needed:
public sealed class Shape permits Circle, Rectangle {
// Both permitted classes must also be immutable
}
Summary for Senior
- In most cases, inheriting from an immutable class is an anti-pattern. Exception: sealed class hierarchy (Java 17+), where all descendants are also immutable.
- Always mark immutable classes as
final - Immutability is not just
finalfields — it also means prohibiting logic changes through polymorphism - Use Sealed classes for controlled inheritance in Java 17+
Interview Cheat Sheet
Must know:
- Technically possible (if not
final), but it’s an anti-pattern — subclass adds mutability - Subclass can: add mutable fields, override getters, make hashCode unstable
- Solution: always
final classfor immutable classes - Alternatives: composition instead of inheritance, sealed classes (Java 17+)
- All fundamental JDK immutable classes are final: String, Integer, BigDecimal, LocalDate
- Sealed classes allow limited inheritance with control over descendants
Frequent follow-up questions:
- Why does inheritance break immutability? — Subclass adds mutable fields or overrides getters
- What if I need to extend functionality? — Composition: wrap the immutable object in a new final class
- Sealed classes vs final? — Sealed permits specific heirs, final prohibits all
- Polymorphism as a threat? — Method relies on immutability, subclass swaps data after validation
Red flags (do NOT say):
- “Inheriting from an immutable class is fine” — it’s an anti-pattern
- “A subclass can’t change final fields” — true, but it can override getters
- “Sealed classes = final” — sealed allows inheritance, but limited
- “You can add a mutable field in a subclass” — that destroys the immutability contract
Related topics:
- [[16. Why should an immutable class be final]]
- [[17. What happens if you override getter in subclass of immutable class]]
- [[3. How to create an immutable class in Java]]
- [[7. What is the final keyword and how does it help create immutable classes]]