advanced.java
← Tous les concepts
Conception des classes · ch. 3, p. 20

Classes immuables

Un objet dont l'état observable ne peut pas changer après construction. Les objets immuables sont automatiquement thread-safe, librement partageables, et sûrs comme clés de map.

La recette :

  • Rendre la classe final, ou tous les constructeurs privés, pour que le comportement ne puisse pas être redéfini.
  • Rendre chaque champ private final.
  • Ne fournir aucun mutateur.
  • Copier défensivement tout composant mutable à l’entrée comme à la sortie.
public final class Money {
    private final BigDecimal amount;
    private final Currency currency;

    public Money(BigDecimal amount, Currency currency) {
        this.amount = Objects.requireNonNull(amount);
        this.currency = Objects.requireNonNull(currency);
    }

    public Money plus(Money other) {          // renvoie une nouvelle instance
        if (!currency.equals(other.currency))
            throw new IllegalArgumentException("currency mismatch");
        return new Money(amount.add(other.amount), currency);
    }
}

La garantie des champs final

Le modèle mémoire fait une promesse spéciale : une fois qu’un constructeur se termine sans laisser this s’échapper, chaque thread voit les valeurs correctement initialisées de ses champs final, sans aucune synchronisation. Laissez this s’échapper du constructeur et la garantie disparaît.

Coût

Chaque modification alloue. C’est généralement sans importance, et là où ça l’est, le motif est un builder mutable produisant un résultat immuable — String et StringBuilder étant la paire canonique.

1 questions sur ce concept S'entraîner