final
declara una referencia de objeto que no se puede modificar, p.
private final Foo something = new Foo();
crea un nuevo Foo
y coloca la referencia en something
.A partir de entonces, no es posible alterar something
para apuntar a una instancia diferente de Foo
.
Esto no no impide la modificación del estado interno del objeto. Todavía puedo llamar a cualquier método en Foo
que esté accesible para el alcance correspondiente. Si uno o más de esos métodos modifica el estado interno de ese objeto, entonces final
no evitará eso.
Como tal, los siguientes:
private final Set<String> fixed = new HashSet<String>();
hace no crear un Set
que no puede ser añadido a o de otra manera alterado; solo significa que fixed
solo hará referencia a esa instancia.
Por el contrario, haciendo:
private Set<String> fixed = Collections.unmodifiableSet(new HashSet<String>());
crea una instancia de un Set
que tirar UnsupportedOperationException
si se intenta llamar fixed.add()
o fixed.remove()
, por ejemplo - el objeto en sí protegerá su estado interno y evitar que se siendo modificado.
Para completarlo:
private final Set<String> fixed = Collections.unmodifiableSet(new HashSet<String>());
crea una instancia de un Set
que no permitirá que su estado interno a ser cambiado, y también significa que fixed
sólo se deberá apuntar a una instancia de ese conjunto.
El motivo por el que final
se puede usar para crear constantes de primitivas se basa en el hecho de que el valor no se puede cambiar. Recuerde que fixed
arriba era solo una referencia, una variable que contiene una dirección que no se puede cambiar. Bueno, para primitivos, p.
private final int ANSWER = 42;
el valor de ANSWER
es que 42. Desde ANSWER
no puede ser cambiado, solamente siempre tendrá el valor 42.
Un ejemplo que borra todas las líneas sería la siguiente:
private final String QUESTION = "The ultimate question";
Según las reglas anteriores, QUESTION
contiene la dirección de una instancia de String
que representa "La última pregunta", y esa dirección no se puede cambiar. Lo que hay que recordar aquí es que el String
es inmutable: no se puede hacer nada con una instancia de String
que lo cambie, y cualquier operación que lo haga (como replace
, substring
, etc.) devolverá referencias completamente diferentes instancias de String
.
Good post. En resumen, la _reference_ no se puede cambiar, pero el _contents_ del objeto * puede *. – extraneon