Endgültig zu sein ist nicht dasselbe wie unveränderlich zu sein.
final != immutable
Das final
Schlüsselwort wird verwendet, um sicherzustellen, dass die Referenz nicht geändert wird (dh die Referenz, die sie hat, kann nicht durch eine neue ersetzt werden).
Wenn das Attribut jedoch selbst geändert werden kann, ist es in Ordnung, das zu tun, was Sie gerade beschrieben haben.
Zum Beispiel
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
Wenn wir diese Klasse instanziieren, können wir dem Attribut keinen anderen Wert zuweisen, someFinalObject
da es endgültig ist .
Das ist also nicht möglich:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor; // not allowed because someFinal is .. well final
Aber wenn das Objekt selbst so veränderlich ist:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Dann kann der in diesem veränderlichen Objekt enthaltene Wert geändert werden.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println( someObject.someFinal ); // prints 3
Dies hat den gleichen Effekt wie Ihr Beitrag:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Hier ändern Sie nicht den Wert von INSTANCE, sondern ändern den internen Status (über die Methode providers.add).
Wenn Sie verhindern möchten, dass die Klassendefinition folgendermaßen geändert wird:
public final class ConfigurationService {
private static final ConfigurationService INSTANCE = new ConfigurationService();
private List providers;
private ConfigurationService() {
providers = new ArrayList();
}
// Avoid modifications
//public static void addProvider(ConfigurationProvider provider) {
// INSTANCE.providers.add(provider);
//}
// No mutators allowed anymore :)
....
Aber es könnte nicht viel Sinn machen :)
Aus dem gleichen Grund müssen Sie übrigens auch den Zugriff darauf synchronisieren .