What happens if you override getter in subclass of immutable class?
If the immutable class is not final, a subclass can override a getter and return different data. This breaks all expectations of code that relies on immutability.
Junior Level
If the immutable class is not final, a subclass can override a getter and return different data. This breaks all expectations of code that relies on immutability.
public class ImmutableBase { // not final — mistake
private final String data;
public ImmutableBase(String data) { this.data = data; }
public String getData() { return data; }
}
public class MutableChild extends ImmutableBase {
private String dynamicData;
public void setDynamicData(String d) { this.dynamicData = d; }
@Override
public String getData() {
// Note: the parent's final field data is still unchanged,
// but getData() returns a different value.
return dynamicData; // substituted result!
}
}
Middle Level
Why this is dangerous
-
Collection logic violation — if an object is in
HashMapand its getter (used inequals()) returns different data — the object becomes impossible to find -
Security vulnerabilities — a security method checks
getData()for forbidden characters, and the subclass substitutes the result after validation -
Loss of thread-safety — the subclass’s getter accesses non-
finalfields without synchronization → “dirty reads” in a multi-threaded environment
How to protect yourself
Always make immutable classes final:
public final class ImmutableBase { ... } // inheritance is impossible
Even with a final class, a getter can return a mutable object — this is another form of immutability violation, see file 29.
Senior Level
The deep problem
Overriding a getter destroys the immutability contract at the business logic level, even if final fields technically haven’t changed. The JMM guarantees visibility of final fields, but it cannot guarantee that a method will return exactly those fields.
Real-world example
public void authorize(ImmutableCredentials creds) {
if (securityManager.check(creds.getToken())) {
// Here a subclass can return a different token
api.call(creds.getToken());
}
}
Solution
finalclass — completely prohibits inheritancesealedclass (Java 17+) — allows only specific, verified heirs- Composition — instead of inheritance
Summary for Senior
- Overriding a getter destroys immutability guarantees through polymorphism
- JMM does not protect against method logic substitution
- Always
finalfor immutable classes sealedclasses — for controlled inheritance
Interview Cheat Sheet
Must know:
- A subclass can override a getter and return different data — immutability contract is broken
- Collection logic violation: object in HashMap becomes unfoundable if getter participates in equals
- Security vulnerabilities: getter substitutes result after validation (TOCTOU)
- Loss of thread-safety: subclass getter accesses non-final fields without synchronization
- JMM guarantees visibility of final fields, but not method logic
- Solution:
finalclass (full prohibition),sealedclass (controlled inheritance), composition
Frequent follow-up questions:
- Parent’s final fields haven’t changed — what’s the problem? — The getter returns DIFFERENT data, breaking the contract
- Example of a real vulnerability? — authorize() checks the token, subclass returns a different token on save
- How does JMM relate to this? — JMM protects final field data, but cannot guarantee the method will return exactly those
- Does sealed class solve the problem? — Yes, if all permitted classes are also immutable
Red flags (do NOT say):
- “Subclass getter is not dangerous — final fields are the same” — getter can return anything
- “This is only a HashMap problem” — no, it’s security, thread-safety, and business logic
- “You can test the getter” — polymorphism allows substitution at runtime
- “Composition is always worse than inheritance” — for immutability, composition is the only safe path
Related topics:
- [[15. Can you inherit from an immutable class]]
- [[16. Why should an immutable class be final]]
- [[7. What is the final keyword and how does it help create immutable classes]]
- [[28. What happens if you modify a mutable key in HashMap]]