最終的であることは、不変であることと同じではありません。
final != immutable
final
キーワードは必ず参照が変更されませんを作るために使用されている(であること、それは新しいもので置換することはできませんしている参照)
ただし、属性が自己変更可能である場合は、今説明したことを実行しても問題ありません。
例えば
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
このクラスをインスタンス化someFinalObject
すると、finalであるため、属性に他の値を割り当てることができなくなります。
したがって、これは不可能です。
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor;
しかし、オブジェクト自体が次のように変更可能である場合:
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 );
これはあなたの投稿と同じ効果があります:
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();
}
....
しかし、それはあまり意味がないかもしれません:)
ちなみに、基本的に同じ理由でアクセスを同期する必要もあります。