# Immutable Objects — Object-Oriented Programming (OOP)

Source: https://www.skillbyai.com/en/oop/e-immutable

> Design immutable classes and understand defensive copying.

## Objects that never change

An **immutable object** cannot change state after construction. Java's `String`, `Integer` and `LocalDate` are immutable; operations such as `toUpperCase()` return **new** objects. Immutability brings big benefits: objects are automatically **thread-safe**, can be **shared** and cached freely, make safe **map keys**, and are easier to reason about because no other code can change them behind your back. To make a class immutable in Java: make all fields **`private final`**; provide **no setters**; make the class **`final`** (or its constructor private) so subclasses cannot add mutability; and use **defensive copies** for mutable inputs and outputs such as lists and arrays, otherwise a caller who still holds the original list can change your object's "immutable" contents. **Records** (Java 16+) make simple immutable data carriers concise. Methods that would "change" an immutable object return a modified copy instead, sometimes called *withers* (`withPrice(...)`).

## An immutable class with defensive copies

Callers cannot modify the internal list, either through the constructor argument or the getter.

```java
import java.util.List;

public final class Order {
    private final String id;
    private final List<String> items;

    public Order(String id, List<String> items) {
        this.id = id;
        this.items = List.copyOf(items);       // defensive copy, and unmodifiable
    }

    public String id() { return id; }
    public List<String> items() { return items; }   // already unmodifiable, safe to return

    public Order withItem(String item) {           // "modify" by returning a new object
        var copy = new java.util.ArrayList<>(items);
        copy.add(item);
        return new Order(id, copy);
    }
}

// Java 16+ record: final fields, constructor, accessors, equals/hashCode/toString
public record Money(long paise, String currency) { }
```

## A printed certificate

A printed certificate does not change; if a detail is wrong, a new certificate is issued. Anyone can hold a copy without worrying that someone else will edit theirs.

**Quiz:** Why does an immutable class make defensive copies of mutable constructor arguments such as lists?

- [ ] To save memory
- [x] So the caller cannot change the object's state later through the list it still holds
- [ ] Because Java requires it
- [ ] To make the class faster

*Answer:* So the caller cannot change the object's state later through the list it still holds. Without a copy, the caller's reference to the same list could modify the object.
