Ответ
Ключевое слово final делает неизменяемым для наследования сам класс, но не делает автоматически неизменяемыми его экземпляры.
Что запрещает final для класса:
- Наследование (расширение) этого класса.
Что НЕ гарантирует final для класса:
- Неизменяемость (immutability) состояния его объектов.
Пример:
// Класс final — его нельзя унаследовать
final class Vehicle {
private int speed; // Поле НЕ final, его можно изменить
public Vehicle(int speed) {
this.speed = speed;
}
// Сеттер изменяет состояние объекта
public void setSpeed(int speed) {
this.speed = speed;
}
}
// Попытка наследования вызовет ошибку компиляции:
// class Car extends Vehicle {} // ОШИБКА: Cannot inherit from final 'Vehicle'
// Однако экземпляры Vehicle остаются изменяемыми:
Vehicle v = new Vehicle(50);
v.setSpeed(100); // Состояние объекта изменено
Чтобы сделать экземпляры неизменяемыми, необходимо:
- Объявить все поля как
private final. - Не предоставлять сеттеров.
- Инициализировать поля только в конструкторе.
- (Опционально) Защищать mutable-поля от изменений (возвращать копии).