Un objeto inmutable es aquel cuyo estado no se puede cambiar una vez
construído. Todos sus atributos han sido definidos como
final
y/o utiliza copia defensiva para protegerse
frente a cambios desde el código cliente.
Por ejemplo, los objetos String
e Integer
de Java son inmutables. Si echas un vistazo a la documentación Java de
estas clases, verás que todos los métodos que en principio alterarían el
estado interno de uno de estos objetos, en realidad
devuelven un nuevo objeto. Por ejemplo, los método
concat()
, replace()
o trim()
de
String. El objeto original no es alterado.
String h = "HOLA";
.concat(" Y ADIOS"); h
deja h
inalterado. ¿por qué?
Para modificar h
,
= h.concat(" Y ADIOS"); h
Entonces, ¿cuántos objetos String se crean a continuación?
= "HOLA";
h = h + " Y ADIOS"; h
Para crear una clase inmutable (desde el punto de vista del código cliente) deberíamos seguir estas reglas:
final
Aunque puede no ser estrictamente necesario (p. ej. si no hay
setters), es conveniente, ya que también previene la
modificación interna.final
Por ejemplo, supongamos que tenemos dos clases, Punto y Circulo y queremos hacer Circulo inmutable.
class Circulo {
public Circulo(Punto p, double r) { origen=p; radio=r; }
public Punto getOrigen() { return origen; }
public double getRadio() { return radio; }
private Punto origen;
private double radio;
}
¿Es esta clase inmutable? Comprueba si cumple las reglas anteriores. O intenta crear un Circulo y modificar su centro o su radio. Si pueddes hacerlo, entonces Circulo no es inmutable.
Solución:
final class Circulo { //regla 5. clase 'final'
public Circulo(Punto p, double r) {
= new Punto(p); // regla 4.1, copia defensiva
origen =r; // no es una referencia, no hay problema.
radio}
public Punto getOrigen() {
return new Punto(origen); // regla 4.2, copia defensiva
}
public double getRadio() { return radio; }
final private Punto origen; //reglas 2 y 3
final private double radio; // reglas 2 y 3
// regla 1: no hay setters
}
Más información: http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html