Short answer
Immutability is the default I reach for when objects are shared across threads or used as map keys, because immutable objects are inherently thread-safe and have stable hashCodes.
Explanation
To do it right: make the class final (or use a sealed/record), all fields private final, no setters, and defensively copy any mutable inputs in the constructor and any mutable return values in getters. Records (Java 16) give you most of this for free but still need defensive copies for mutable components.
Common mistakes
- Making fields final but exposing a mutable List without a defensive copy.
- Forgetting to make the class final (or the constructor private).