Я вижу большинство неизменных POJO, написанных так:
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;
}
}
Тем не менее, я склонен писать их так:
public class MyObject {
public final String foo;
public final int bar;
public MyObject(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
Обратите внимание, что ссылки являются окончательными, поэтому объект по-прежнему неизменен. Это позволяет мне писать меньше кода и обеспечивает более короткий (на 5 символов: get
и ()
) доступ.
Единственный недостаток, который я вижу, - если вы хотите изменить реализацию getFoo()
в будущем, чтобы сделать что-то сумасшедшее, вы не можете. Но на самом деле этого никогда не происходит, потому что Объект неизменен; Вы можете проверить во время создания экземпляра, создать неизменные защитные копии во время создания экземпляра (см., ImmutableList
например, Guava ) и получить объекты foo
или, bar
готовые к get
вызову.
Есть ли недостатки, которые я пропускаю?
РЕДАКТИРОВАТЬ
Полагаю, еще один недостаток, который мне не хватает, - это библиотеки сериализации, использующие рефлексию над методами, начинающимися с get
или is
, но это довольно ужасная практика ...
String
, int
или MyObject
. В первой версии final
только для того, чтобы гарантировать, что другие методы, кроме конструктора внутри класса, не пытаются bar = 7;
, например. Во втором варианте, final
необходимо , чтобы предотвратить потребителей делать: MyObject x = new MyObject("hi", 5); x.bar = 7;
.
Object
все еще неизменны». Вводит в заблуждение - таким образом, кажется, вы думаете, что что-то final Object
неизменно, а это не так. Извините за недопонимание.
myObj.getFoo().setFrob(...)
.
final
не делает переменную неизменным объектом. Обычно я использую дизайн, в котором я определяюfinal
поля перед созданием обратного вызова, чтобы обратный вызов мог получить доступ к этим полям. Конечно, он может вызывать все методы, включая любыеsetX
методы.