Какую цель преследует объявление класса как `final` в Java?

«Какую цель преследует объявление класса как `final` в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Объявление класса как final в Java запрещает его наследование — от такого класса нельзя создавать подклассы. Это мощный инструмент проектирования для обеспечения безопасности, целостности и производительности.

Основные причины использования final классов:

  1. Гарантия безопасности и неизменности (Security & Immutability):

    • Критически важные классы, такие как String, Integer, Double, объявлены final, чтобы никто не мог создать подкласс и изменить их поведение (например, подменить метод equals() или hashCode()).
    • Это ключевое условие для создания истинно неизменяемых (immutable) объектов.
  2. Защита проектных решений (Design Enforcement):

    • Предотвращает нарушение внутренних инвариантов класса через наследование и переопределение методов.
    • Гарантирует, что логика класса останется именно такой, как задумал автор.
  3. Оптимизация производительности (Performance Optimization):

    • JVM может применять агрессивные оптимизации (например, встраивание методов — method inlining), так как ей точно известно, что у класса нет подклассов и виртуальная таблица методов (vtable) не будет меняться.

Пример неизменяемого final класса:

public final class ImmutablePoint {
    private final int x; // Поля final
    private final int y;

    public ImmutablePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
    // Только геттеры, нет сеттеров
    public int getX() { return x; }
    public int getY() { return y; }
}
// Попытка наследования вызовет ошибку компиляции:
// class ExtendedPoint extends ImmutablePoint { } // ОШИБКА: Cannot inherit from final 'ImmutablePoint'

Когда стоит использовать? Для классов-утилит (например, Math), классов-значений (Value Objects), API-классов, где важно строго контролировать поведение.