public class Inmutable {
//los primitivos son inmutables por defecto
private final int id;
//String es una clase inmutable
private final String nombre;
//List no se puede saber si es inmutable pero eso tiene arreglo
//la clase a almacenar en esta lista también debe ser inmutable
//sino Inmutable no sería del todo inmutable
private final List<BigDecimal> listaNumeros;
//En Java, la clase java.util.Date no es inmutable
//por ende, para trabajar con una fecha en una clase inmutable
//hay dos opciones: 1) Almacenar el long que representa al tiempo
//en lugar de almacenar Date. 2) Utilizar clases de un API que provee
//manejo de fechas para Java como Joda Time o Date and Time disponible
//desde Java 8 en el paquete java.time
//Para este caso, utilizaré la opción 1)
private final long fechaNacimiento;
//en el constructor se deben inicializar todos los campos
//ojo: se recibe un como parámetro
public Inmutable(int id, String nombre, List<BigDecimal> listaNumeros, Date fechaNacimiento) {
this.id = id;
this.nombre = nombre;
//para el caso de la lista, se decora para que sea inmutable
this.listaNumeros = Collections.unmodifiableList(listaNumeros);
//en el caso de Date, se almacena solo el valor entero
this.fechaNacimiento = fechaNacimiento.getTime();
}
//se crean getters para acceder a los campos
//se devuelve el primitivo puesto que no se puede modificar su valor
public int getId() {
return this.id;
}
//se devuelve la instancia directamente puesto que no se puede modificar su estado
public String getNombre() {
return this.nombre;
}
//se puede devolver esta lista puesto que ya es inmutable
//no hay problema si el cliente intenta modificarla
//se lanzara una excepción por el comportamiento de la lista
//devuelta por Collections#unmodifiableList
public List<BigDecimal> getListaNumeros() {
return this.listaNumeros;
}
//se devuelve una instancia de Date para el cliente de esta clase
//puesto que esta instancia de Date no está asociada a la clase
//no importa si el cliente modifica su estado
public Date getFechaNacimiento() {
return new Date(fechaNacimiento);
}
//se agregan dos operaciones
//una para agregar valores a la lista de numeros
//otro para "cambiar" la fecha de nacimiento
public Inmutable agregaNumero(BigDecimal numero) {
//preparamos la nueva lista a utilizar
List<BigDecimal> nuevaListaNumeros = new ArrayList<>(listaNumeros);
nuevaListaNumeros.add(numero);
//siempre se crea una nueva instancia a devolver
//de esta forma la instancia actual no altera su estado
return new Inmutable(id, nombre, nuevaListaNumeros, new Date(fechaNacimiento));
}
public Inmutable setFechaNacimiento(Date fechaNacimiento) {
return new Inmutable(id, nombre, listaNumeros, fechaNacimiento);
}
}
public class Mutable {
private int id;
Mutable(int id) {
this.id=id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id=id;
}
}
public class Inmutable {
//final cumple dos roles
//1. Forzar que se inicialize el campo 1 sola vez en la clase
// y que no se le pueda cambiar el valor
//2. Fuerza que el campo se inicie en el constructor de la clase
private final int id;
Inmutable(int id) {
this.id=id;
}
public int getId() {
return id;
}
}
Ipman1971 的回答部分正确。一个类在它允许其状态被改变时是可变的,即通过使其字段公开或通过提供允许改变字段值的方法来修改它所包含的字段的值.
不可变类不仅不提供允许修改其状态的方法,而且一旦该类的对象被初始化,它的状态就不能以任何方式改变。任何导致状态改变的操作实际上都会返回一个相同类的新对象,但状态改变了。为此,类定义中必须满足以下条件:
final
到字段来实现的。final
)。这是一个牢记所有这些方面的不可变类的示例:
好吧,我想您很快就会明白,可变对象具有可以更改其值的属性,为此,该类具有允许修改属性的方法。
不可变对象是不允许修改其属性的对象,它们在创建时分配并且无法修改。我给你举个例子: