Immutable object
An immutable object is one whose state cannot change after construction. Java has several famous immutables: String, all wrapper classes (Integer, Longβ¦), java.time types (LocalDate, Instantβ¦), and all records (when components are immutable).
Building an immutable class
public final class Money {
private final long cents;
private final String currency;
public Money(long cents, String currency) {
this.cents = cents;
this.currency = Objects.requireNonNull(currency);
}
public long cents() { return cents; }
public String currency() { return currency; }
public Money plus(Money other) {
if (!currency.equals(other.currency)) throw new IllegalArgumentException();
return new Money(cents + other.cents, currency); // returns a NEW object
}
}
Immutability checklist
- Mark the class
final(so it cannot be subclassed and mutated). - All fields are
private final. - No setters. No methods that modify state.
- If a field is a mutable type (
Date,List), make defensive copies in the constructor and in accessors, or use immutable equivalents (Instant,List.copyOf()).
Why immutability matters
- Thread-safe by construction β no synchronization needed to share across threads.
- Safe as map keys and set elements β hashCode cannot change.
- Easier to reason about β no state changes to track through the code.
- Free caching β two identical immutable objects are interchangeable.
Records make it easy
public record Money(long cents, String currency) {}
// Immutable for free β components are final, no setters possible.