Sobes.tech
Middle

Comment rendre une classe en Java immuable?

sobes.tech IA

Réponse de l'IA

Pour rendre une classe en Java immuable, il faut suivre les principes suivants :

  1. Marquer la classe comme final. Cela empêchera l'héritage, qui pourrait conduire à modifier l'état.
  2. Rendre tous les champs de la classe privés (private). Cela limitera l'accès direct aux champs depuis l'extérieur de la classe.
  3. Ne pas fournir de setters (méthodes pour modifier l'état des champs).
  4. Rendre tous les champs mutables de la classe final. Cela garantit que les références aux objets mutables ne peuvent pas être modifiées après l'initialisation.
  5. Si la classe contient des références à des objets mutables (par exemple, java.util.Date, collections), lors de leur retour depuis les getters ou leur passage au constructeur, il faut créer et retourner des copies de ces objets. Cela s'appelle "copie profonde".

Exemple :

// Exemple de classe immuable
final class ImmutablePerson {
    private final String name;
    private final int age;
    private final List<String> hobbies; // Champ mutable

    // Constructeur avec copie profonde des champs mutables
    public ImmutablePerson(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        // Créer une copie de la liste hobbies
        this.hobbies = new ArrayList<>(hobbies);
    }

    // Getters
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    // Retourner une copie de la liste hobbies pour éviter les modifications externes
    public List<String> getHobbies() {
        return Collections.unmodifiableList(new ArrayList<>(this.hobbies));
    }

    // Redéfinir toString pour la commodité
    @Override
    public String toString() {
        return "ImmutablePerson{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", hobbies=" + hobbies +
               '}';
    }
}

Exemple d'utilisation :

// Exemple d'utilisation d'une classe immuable
List<String> initialHobbies = new ArrayList<>();
initialHobbies.add("Reading");
initialHobbies.add("Hiking");

ImmutablePerson person = new ImmutablePerson("Alice", 30, initialHobbies);

// Tenter de modifier la liste obtenue entraînera une exception
List<String> retrievedHobbies = person.getHobbies();
// retrievedHobbies.add("Coding"); // Lancerait UnsupportedOperationException

// Modifier la liste initiale n'affectera pas l'objet ImmutablePerson
initialHobbies.add("Painting");

System.out.println(person); // Affiche : ImmutablePerson{name='Alice', age=30, hobbies=[Reading, Hiking]}
System.out.println(initialHobbies); // Affiche : [Reading, Hiking, Painting]