Being final is not the same as being immutable.
final != immutable
The final
keyword is used to make sure the reference is not changed ( that is, the reference it has can't be substituted with a new one )
But, if the attribute is self is modifiable it is ok to do what you have just described.
For instance
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
If we instantiate this class, we won't be able to assign other value to the the attribute someFinalObject
because it is final.
So this is not possible:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor; // not allowed because someFinal is .. well final
But if the object it self is mutable like this:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Then, the value contained by that mutable object may be changed.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println( someObject.someFinal ); // prints 3
This has the same effect that your post:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Here you are not changing the value of INSTANCE, your are modifying its internal state ( via, providers.add method )
if you want to prevent that the class definition should be changed like this:
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 :)
....
But, it might not make much sense :)
By the way, you also have to synchronize access to it basically for the same reason.