Что означает модификатор final для переменной в Java?

Ответ

Модификатор final для переменной означает, что значение этой переменной может быть присвоено только один раз (при объявлении или в конструкторе/инициализаторе). После инициализации его нельзя изменить.

Типы final-переменных:

  1. final-примитив: Значение становится константой.

    final int MAX_USERS = 100;
    // MAX_USERS = 200; // Ошибка компиляции!
  2. final-ссылка на объект: Нельзя изменить саму ссылку, но состояние объекта может меняться.

    final List<String> names = new ArrayList<>();
    names.add("Алиса"); // Можно: изменяем состояние объекта
    // names = new LinkedList<>(); // Ошибка: нельзя переприсвоить ссылку

Особенности инициализации:

  • Поле класса: Должно быть инициализировано к моменту завершения работы каждого конструктора.
  • Статическое final-поле (константа): Должно быть инициализировано при объявлении или в статическом блоке.
  • Локальная переменная: Должна быть инициализирована до первого использования.

Практическое применение:

  • Создание констант (public static final).
  • Гарантия, что ссылка на объект, переданная в метод, не будет заменена внутри метода.
  • Использование в анонимных классах для доступа к локальным переменным (они должны быть final или effectively final).

Ответ 18+ 🔞

Да ты посмотри, какая интересная хуйня, этот final! Ну, в смысле, модификатор такой. Представь себе — ты объявил переменную и прикрутил к ней этот самый final, и всё, пиши пропало. Значение ей можно дать ровно один раз, как первую и последнюю зарплату. Дальше хоть тресни — не переприсвоишь.

Ну и какие они бывают, эти final-переменные:

  1. Примитив final'ный. Всё, константа, точка. Запомнил число и носи его с собой.

    final int MAX_USERS = 100;
    // MAX_USERS = 200; // Ёпта, компилятор тебе мозги выест! Нельзя!
  2. Ссылка final'ная. Вот тут, блядь, тонкий момент, многие об него запнутся. Саму ссылку — ту самую, которая на объект указывает — менять низя. А вот внутрь объекта залезть и там всё перевернуть — пожалуйста, на здоровье!

    final List<String> names = new ArrayList<>();
    names.add("Алиса"); // Можно! Состояние объекта меняем, ссылка та же.
    // names = new LinkedList<>(); // А вот это уже пиздец, ошибка! Куда ссылку понес, мудак?

А теперь, сука, про инициализацию, чтоб ты понимал, где подвох:

  • Поле в классе. Его нужно проинициализировать так, чтобы к моменту, когда конструктор свою работу заканчивает, всё было готово. В каждом конструкторе, блядь!
  • Статическое final-поле (она же константа). Вообще красота. Инициализируй при объявлении, либо в статическом блоке — и спи спокойно.
  • Локальная переменная. Проще простого: инициализируй до того, как в первый раз использовать собрался. Не инициализируешь — получишь по ебалу от компилятора.

И где это, блядь, применять-то?

  • Константы делать, самые что ни на есть public static final.
  • Чтобы в метод передать объект и быть уверенным, что тебе внутри метода ссылку не подменят на какую-нибудь левую хуйню.
  • В анонимных классах, эти твои, чтобы к локальным переменным из внешнего метода достучаться — они должны быть final или effectively final, иначе нихуя не получится. Вот такая, блядь, магия!