Nihai olmak, değişmez olmakla aynı şey değildir.
final != immutable
final
Anahtar emin referans değişmez hale getirmek için kullanılır (olduğu, yeni bir tanesi ile ikame edilen edilemez olan referans)
Ancak, eğer öznitelik değiştirilebilirse, az önce tarif ettiğiniz şeyi yapmanızda bir sakınca yoktur.
Örneğin
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
Bu sınıfı somutlaştırırsak someFinalObject
, son niteliğe sahip olduğu için özniteliğe başka bir değer atayamayız. .
Yani bu mümkün değil:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor;
Ama eğer nesne kendiliğinden böyle değiştirilebilirse:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Daha sonra, bu değiştirilebilir nesnenin içerdiği değer değiştirilebilir.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println( someObject.someFinal );
Bu, gönderinizle aynı etkiye sahiptir:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Burada INSTANCE'ın değerini değiştirmiyorsunuz, dahili durumunu değiştiriyorsunuz (provider.add yöntemi aracılığıyla)
Sınıf tanımının şu şekilde değiştirilmesini önlemek istiyorsanız:
public final class ConfigurationService {
private static final ConfigurationService INSTANCE = new ConfigurationService();
private List providers;
private ConfigurationService() {
providers = new ArrayList();
}
....
Ama pek mantıklı gelmeyebilir :)
Bu arada, temelde aynı nedenden ötürü erişimi de senkronize etmeniz gerekiyor .