¿Cómo haces una clase verdaderamente inmutable en Java?
Opciones
- Marcando solo la clase como
final; no hace falta nada más - Clase
final, campos private final, sin setters, con copias (Opción correcta) - Añadiendo
volatilea todos los campos de la clase - Haciendo
statictodos 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.