Veo los POJO más inmutables escritos así:
public class MyObject {
private final String foo;
private final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public String getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
Sin embargo, tiendo a escribirlos así:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Tenga en cuenta que las referencias son finales, por lo que el objeto sigue siendo inmutable. Me permite escribir menos código y permite un acceso más corto (por 5 caracteres: el get
y ()
).
La única desventaja que puedo ver es que si quieres cambiar la implementación getFoo()
en el futuro para hacer algo loco, no puedes. Pero de manera realista, esto nunca sucede porque el Objeto es inmutable; puede verificar durante la creación de instancias, crear copias defensivas inmutables durante la creación de instancias (consulte Guava's, ImmutableList
por ejemplo) y preparar los objetos foo
u bar
para la get
llamada.
¿Hay alguna desventaja que me falta?
EDITAR
Supongo que otra desventaja que me falta son las bibliotecas de serialización que utilizan la reflexión sobre los métodos que comienzan con get
o is
, pero esa es una práctica bastante terrible ...
String
, int
o MyObject
. En la primera versión, final
es solo para garantizar que otros métodos que no sean el constructor dentro de la clase no intenten bar = 7;
, por ejemplo. En la segunda versión, final
es necesario evitar que los consumidores haciendo: MyObject x = new MyObject("hi", 5); x.bar = 7;
.
Object
sigue siendo inmutable " es engañoso, de esa manera parece que cree que cualquiera final Object
es inmutable, lo que no lo es. Perdón por el malentendido.
myObj.getFoo().setFrob(...)
.
final
no hace que una variable sea el objeto inmutable. Normalmente uso un diseño donde definofinal
campos antes de crear la devolución de llamada para que la devolución de llamada pueda acceder a esos campos. Por supuesto, puede llamar a todos los métodos, incluidos lossetX
métodos.