Être définitif n'est pas la même chose qu'être immuable.
final != immutable
Le final
mot-clé est utilisé pour s'assurer que la référence n'est pas modifiée (c'est-à-dire que la référence qu'elle possède ne peut pas être remplacée par une nouvelle)
Mais si l'attribut self est modifiable, vous pouvez faire ce que vous venez de décrire.
Par exemple
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
Si nous instancions cette classe, nous ne pourrons pas attribuer une autre valeur à l'attribut someFinalObject
car il est final .
Donc ce n'est pas possible:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor;
Mais si l'objet lui-même est mutable comme ceci:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Ensuite, la valeur contenue par cet objet mutable peut être modifiée.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println( someObject.someFinal );
Cela a le même effet que votre message:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Ici, vous ne changez pas la valeur de INSTANCE, vous modifiez son état interne (via la méthode, provider.add)
si vous voulez éviter que la définition de classe ne soit modifiée comme ceci:
public final class ConfigurationService {
private static final ConfigurationService INSTANCE = new ConfigurationService();
private List providers;
private ConfigurationService() {
providers = new ArrayList();
}
....
Mais cela n'a peut-être pas beaucoup de sens :)
En passant, vous devez également synchroniser l'accès à celui-ci pour la même raison.