Je vois les POJO les plus immuables écrits comme ceci:
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;
}
}
Pourtant, j'ai tendance à les écrire comme ceci:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Notez que les références sont finales, donc l'objet est toujours immuable. Cela me permet d’écrire moins de code et autorise un accès plus court (par 5 caractères: le get
et ()
).
Le seul inconvénient que je peux voir, c'est que si vous voulez modifier la mise en œuvre de getFoo()
la suite pour faire quelque chose de fou, vous ne pouvez pas. Mais de manière réaliste, cela ne se produit jamais car l'objet est immuable; vous pouvez vérifier pendant l'instanciation, créer des copies défensives immuables pendant l'instanciation (voir Guava, ImmutableList
par exemple) et préparer les objets foo
ou bar
pour l' get
appel.
Y a-t-il des inconvénients qui me manquent?
MODIFIER
Je suppose qu’un autre inconvénient qui me manque est la sérialisation des bibliothèques utilisant la réflexion par rapport aux méthodes commençant par get
ou is
, mais c’est une pratique plutôt terrible ...
String
, int
ou MyObject
. Dans la première version, il final
s'agit uniquement de s'assurer que des méthodes autres que le constructeur de la classe n'essayent pas bar = 7;
, par exemple. Dans la deuxième version, final
est nécessaire pour empêcher les consommateurs de faire: MyObject x = new MyObject("hi", 5); x.bar = 7;
.
Object
reste immuable. » Est trompeur - de cette façon , il semble que vous pensez que tout final Object
est immuable, qu'il n'est pas. Désolé pour le malentendu.
myObj.getFoo().setFrob(...)
.
final
ne fait pas une variable l'objet immuable. J'utilise normalement une conception dans laquelle je définis desfinal
champs avant de créer un rappel afin que ce dernier puisse accéder à ces champs. Bien sûr, il peut appeler toutes les méthodes, y compris toutes lessetX
méthodes.