Ключевое слово final
Смысл final зависит от места объявления.
| Где | Что запрещено |
|---|---|
| переменная/поле | повторное присваивание после инициализации |
| параметр | присваивание нового значения внутри метода |
| метод | переопределение в наследнике |
| класс | наследование от класса |
final class Price {
private final BigDecimal amount;
Price(BigDecimal amount) {
this.amount = amount;
}
}
final List<String> items = new ArrayList<>();
items.add("book"); // допустимо
// items = List.of(); // нельзя переназначить ссылкуBlank final и константы
Поле final можно не присваивать в объявлении, но каждый конструктор обязан присвоить его ровно один раз. Константой обычно называют static final примитив или неизменяемый объект с именем в UPPER_SNAKE_CASE.
Только compile-time константы подставляются компилятором в клиентский байткод. Если изменить такую константу в библиотеке, клиент желательно перекомпилировать.
Модель памяти
Для корректно сконструированного объекта Java Memory Model даёт специальные гарантии видимости final-полей. Гарантия может быть нарушена плохим проектированием, если this «утёк» до окончания конструктора. Она не делает потокобезопасными объекты, на которые ссылается поле.
Ограничения
finalне означает immutable;final-метод всё ещё может быть перегружен;private-метод фактически не переопределяется, поэтомуfinalдля него избыточен;- локальная
final-переменная должна быть определённо присвоена до чтения.
На собеседовании
Можно ли изменить объект через final-ссылку? Да, если сам объект изменяем.
Чем final-метод отличается от static? Первый участвует в динамическом вызове, но запрещает переопределение; второй выбирается статически.
Можно ли присвоить blank final в каждом конструкторе? Да, ровно один раз на каждом пути.
Зачем финальные поля immutable-классу? Они фиксируют ссылки/значения и дают дополнительные гарантии публикации.
Связано: Immutable классы и данные, Java Memory Model.