Ser final no es lo mismo que ser inmutable.
final != immutable
La palabra clave final
se utiliza para asegurarse de que la referencia no se cambia (es decir, la referencia que se no puede ser sustituido por uno nuevo)
Pero, si el atributo es el yo es modificable, está bien hacer lo que acabas de describir.
Por ejemplo
class SomeHighLevelClass {
public final MutableObject someFinalObject = new MutableObject();
}
Si creamos una instancia de esta clase, no seremos capaces de asignar otro valor para el atributo someFinalObject
porque es última.
Así que esto no es posible:
....
SomeHighLevelClass someObject = new SomeHighLevelClass();
MutableObject impostor = new MutableObject();
someObject.someFinal = impostor; // not allowed because someFinal is .. well final
Pero si el objeto en sí es mutable como esto:
class MutableObject {
private int n = 0;
public void incrementNumber() {
n++;
}
public String toString(){
return ""+n;
}
}
Entonces, el valor contenido por ese objeto mutable se pueden cambiar.
SomeHighLevelClass someObject = new SomeHighLevelClass();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
someObject.someFinal.incrementNumber();
System.out.println(someObject.someFinal); // prints 3
Esto tiene el mismo efecto que su mensaje:
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
Aquí no va a cambiar el valor de ejemplo, su están modificando su estado interno (vía, método providers.add)
si desea evitar que la definición de la clase debe ser cambiado como esto:
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 :)
....
Pero, podría no tener mucho sentido :)
Por cierto, también tiene que synchronize access to it básicamente por la misma razón.
Este concepto erróneo aparece con bastante frecuencia, no necesariamente como una pregunta. A menudo como una respuesta o comentario. – Robin
Explicación simple de JLS: ** "Si una variable final contiene una referencia a un objeto, entonces el estado del objeto puede cambiarse mediante operaciones en el objeto, pero la variable siempre se referirá al mismo objeto." ** [Documentación de JLS] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4) – realPK