La classe suivante n’est pas immuable. Pourquoi ? Choisissez la proposition la plus complète.
public class Zoo {
private final List<Animal> animals;
public Foo(List<Animal> animals) {
this.animals = Collections.unmodifiableList(animals);
}
public List<Animal> getAnimals() {
return new ArrayList<>(animals);
}
// autres méthodes privées utilisant l'attribut animals
}
A. Car la classe Zoo n’est pas déclarée final.
B. Car la classe possède un getter donnant accès à un attribut de la classe directement.
C. Car la classe Animal peut être muable
D. Car l’attribut animals peut être modifié
E. Pour les raisons A, C et D
F. Pour les raisons A, B et C
G. Pour les raisons A et C
H. Pour les raisons A et D
I. Pour toutes les raisons ci-dessus
Solution
Afin de garantir l’immuabilité, il faut s’assurer que la classe soit final, autrement les sous-classes pourraient la briser.
Si la classe Animal se trouve être muable, il est tout à fait possible d’accéder, depuis l’intérieur ou l’extérieur, à un des objets de type Animal et de le modifier. Le fait qu’une copie de la liste soit effectuée avant d’être renvoyée dans le getter ne change rien à cela.
Malgré le fait que la classe Zoo n’ait accès qu’à une vue non-modifiable de la liste animals, la liste n’est en elle-même pas forcément immuable, elle peut être modifiée ailleurs dans le code. Cet exemple permet d’illustrer la situation:
List<Integer> original = new ArrayList<>();
List<Integer> nonmodifiable = Collections.unmodifiableList(original);
System.out.println(nonmodifiable);
original.add(5);
System.out.println(nonmodifiable);
// Output: [] et [5]
Le fait que la classe possède un getter n’est pas un problème en soi, vu qu’une copie de la liste est effectuée à chaque fois.
La réponse correcte est donc la réponse E