final
просто означает, что переменной / примитиву не может быть присвоено новое значение. Это не то же самое, что const
концепция (которой нет в Java); НЕ гарантирует неизменность. String
в Java, конечно, уже достаточно неизменен (за исключением неприятных атак отражением).
Использование модификатора final
для аргументов параметров не повлияет на безопасность или сборку мусора. Это сделано для удобства чтения и обеспечения соблюдения правил кодирования, чтобы переменные параметров не использовались повторно в методе для хранения других значений.
При обнаружении модификатора final
читатель-человек может быть уверен, что значение этой переменной, после ее присвоения, не изменится в пределах ее видимости. Компилятор будет применять это поведение и не будет компилировать программу, которая незаконно пытается присвоить новое значение переменной, которая объявлена final
.
Переменная может быть объявлена final
. Переменная final
может быть назначена только один раз. Это ошибка времени компиляции, если назначена переменная final
, если только она не была определенно назначена непосредственно перед назначением.
Как уже упоминалось, однако, final
само по себе не гарантирует неизменности объекта, на который ссылаются. Объявление final StringBuilder sb
гарантирует, что sb
, однажды назначенный и находящийся в пределах его области действия, не будет ссылаться на другой экземпляр StringBuilder
. StringBuilder
Сам, конечно, изменчивый объект.
final
и внутренние классы
Другое использование модификатора final
- разрешить использование локальных переменных и т. Д. Внутренним классом:
Любая локальная переменная, формальный параметр метода или параметр обработчика исключений, используемые, но не объявленные во внутреннем классе, должны быть объявлены final
.
Это связано с тем, как внутренние классы, использующие эти переменные, компилируются в Java, деталь реализации, которая, возможно, не слишком важна для обсуждения. По сути, значения этих final
переменных передаются внутренним классам во время построения. Последующие изменения локальных переменных (если они разрешены) не будут видны внутреннему экземпляру класса. Для обеспечения правильной семантики эти локальные переменные должны быть объявлены final
.
Эффекты модификатора final
для локальных переменных во время выполнения
Модификатор
final
для локальных переменных / параметров формального метода является концепцией времени компиляции и не присутствует, скажем, на уровне байт-кода (то есть он играет совсем другую роль, чем модификатор final
для полей, классов и методы). Таким образом, эта концепция просто не существует во время выполнения, где final
и не- final
локальные переменные неразличимы; использование самого ключевого слова не повлияет на сбор и / или сборку мусора.
Возможность сбора мусора определяется с точки зрения наличия или отсутствия живых ссылок на объект. Локальные переменные и аргументы метода выходят из области видимости в конце метода (или блока, в котором они объявлены), независимо от того, объявлены они или нет final
. Выход за рамки означает, что ссылка "мертвая". Сам объект может иметь живые ссылки из других источников.
В этом конкретном случае формальные параметры метода объявляются final
, чтобы их можно было использовать во внутреннем классе. Как упоминалось выше, внутренний класс будет копировать эти ссылки для собственного использования. Таким образом, в данном конкретном случае объект Authenticator
будет иметь ссылки на объекты String
, на которые ссылаются a
и b
.
Проще говоря, чем больше ссылок на объект, тем сложнее его квалифицировать как мусор, неразборчивый для сбора. Однако основным фактором является живучесть этих ссылок, а не то, являются ли они final
.
При профилировании
Хорошо понимать концепции, чтобы снять любые сомнения по поводу использования памяти / проблем с производительностью;лучше просто профилировать и посмотреть, являются ли проблемы реальными, и исправить их по мере необходимости.Хорошо спроектированная система должна быть легко адаптируемой к такого рода изменениям.