Я бачу більшість непорушних 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) та підготуйте fooабо barоб'єкти готові до getвиклику.
Чи є якісь недоліки, яких мені не вистачає?
EDIT
Думаю, ще один недолік, якого мені не вистачає, - це бібліотеки серіалізації, що використовують роздуми над методами, починаючи з 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методи.