Что делает ключевое слово `final` в Java?

Ответ

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

Применение в трёх контекстах:

  1. final переменная/поле: Значение может быть присвоено только один раз (константа).

    final int MAX_USERS = 100;
    // MAX_USERS = 200; // Ошибка компиляции: cannot assign a value to final variable

    Для ссылочных типов неизменна сама ссылка, но состояние объекта можно менять.

    final List<String> list = new ArrayList<>();
    list.add("Hello"); // Можно: изменяется объект, а не ссылка
    // list = new ArrayList<>(); // Ошибка: нельзя изменить ссылку
  2. final метод: Невозможно переопределить (override) в дочерних классах.

    class Parent {
        final void secureMethod() {
            System.out.println("Этот метод нельзя изменить.");
        }
    }
    class Child extends Parent {
        // void secureMethod() { ... } // Ошибка компиляции
    }
  3. final класс: Невозможно унаследовать (extend).

    final class ImmutableClass { /* ... */ }
    // class SubClass extends ImmutableClass { } // Ошибка компиляции

Зачем это нужно? Для обеспечения безопасности, неизменяемости (immutability), проектирования API и предотвращения случайных изменений.

Ответ 18+ 🔞

Да ты посмотри, какая хитрая жопа эта Java придумала! Вот есть у них словечко final, и оно, блядь, как гвоздём прибивает всё нахуй, чтобы не шаталось.

Представь, ты объявил что-то final — и всё, пиздец, приехали. Дальше него ни туды, ни сюды. Как будто на хуй повесил табличку «Не трогать, а то вманжу».

И применяется эта панацея в трёх местах, вот смотри:

  1. final переменная или поле. Это типа константа, ёпта. Один раз присвоил — и хватит, блядь, на всю оставшуюся жизнь.

    final int MAX_USERS = 100;
    // MAX_USERS = 200; // Ошибка компиляции: cannot assign a value to final variable

    А вот если это ссылка на объект — тут прикол, блядь. Саму ссылку поменять нельзя, а вот внутрь объекта лезть и там всё переставлять — пожалуйста, на здоровье.

    final List<String> list = new ArrayList<>();
    list.add("Hello"); // Можно, потому что мы не ссылку меняем, а в объекте ковыряемся.
    // list = new ArrayList<>(); // А вот это уже ни-ни, блядь! Ссылку трогать низя!
  2. final метод. Это, сука, такой метод, который в наследниках переписать нельзя. Захотел папаша, чтобы его фирменный метод остался в неприкосновенности — обозвал его final и спит спокойно.

    class Parent {
        final void secureMethod() {
            System.out.println("Этот метод нельзя изменить, иди нахуй.");
        }
    }
    class Child extends Parent {
        // void secureMethod() { ... } // Ошибка компиляции! Не выйдет, сынок.
    }
  3. final класс. А это вообще, блядь, высшая мера защиты. Такой класс наследовать нельзя, и всё тут. Как будто поставили бетонную стену с колючкой.

    final class ImmutableClass { /* ... */ }
    // class SubClass extends ImmutableClass { } // Ошибка компиляции! Не-а, не судьба.

А нахуя это всё? Да чтобы спать спокойно, блядь! Чтобы какой-нибудь умник в твоём коде ничего лишнего не сломал, чтобы API был предсказуемым, а данные — неизменяемыми. Простота, ёпта, надёжность. Волнение ебать — ноль.