最終的であることは、不変であることと同じではありません。
final != immutable
キーワードは、参照が変更されていないことを確認するために使用されますfinal
(つまり、参照を新しいものに置き換えることはできません)。
ただし、属性が self である場合は、今説明したことを実行しても問題ありません。
例えば
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
このクラスをインスタンス化すると、finalsomeFinalObject
であるため、属性に他の値を割り当てることができなくなります。
したがって、これは不可能です。
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor; // not allowed because someFinal is .. well final
しかし、オブジェクト自体が次のように可変である場合:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
次に、その変更可能なオブジェクトに含まれる値が変更される可能性があります。
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println( someObject.someFinal ); // prints 3
これはあなたの投稿と同じ効果があります:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
ここでは、INSTANCE の値を変更しているのではなく、その内部状態を変更しています ( providers.add メソッドを介して)
クラス定義を次のように変更する必要があるのを防ぎたい場合:
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 :)
....
しかし、それはあまり意味がないかもしれません:)
ちなみに、基本的に同じ理由で、アクセスも同期する必要があります。