Repaso
English
Java CoreAvanzadoJV-33

¿Cómo haces una clase verdaderamente inmutable en Java?

Opciones

  1. Marcando solo la clase como final; no hace falta nada más
  2. Clase final, campos private final, sin setters, con copias (Opción correcta)
  3. Añadiendo volatile a todos los campos de la clase
  4. Haciendo static todos los campos para que los objetos los compartan

Respuesta

Haz la clase final, todos los campos private final, sin setters, y copia de forma defensiva cualquier objeto mutable que entre o salga

Por qué

Un objeto inmutable nunca cambia tras construirse, así que es thread-safe de forma automática y se puede compartir y guardar en caché libremente (String y LocalDate son inmutables).

Receta: (1) clase final para que nadie cree subclases que añadan mutabilidad, (2) campos private final, (3) sin setters, (4) si un campo es un objeto mutable (una List, un Date), cópialo en el constructor y devuelve una copia o una vista no modificable en el getter.

Un campo final List por sí solo no basta: el contenido de la lista aún podría cambiar. Los records hacen casi todo esto por ti (pero siguen necesitando copias defensivas de los componentes mutables).

public final class Team {
    private final List<String> members;
    public Team(List<String> m) { this.members = List.copyOf(m); }
    public List<String> members() { return members; }  // already unmodifiable
}

Recuerda

Campos final + sin setters + copias defensivas.

Términos clave

Practica esta pregunta en Repaso