Ключевое слово "final" действительно имеет некоторые последствия для безопасности. Представьте, что вы разрабатываете безопасную систему, в которой есть служба, которая при наличии строки делает что-то, если и только если строка допустима. Вы можете написать:
public void doSomethingUseful(String argument) {
checkValidity(argument);
/* prepare to do something useful... preparation takes a bit of time! */
reallyDoTheUsefulTask(argument);
}
Если бы String не был последним, какой-нибудь умный злоумышленник мог бы создать подкласс String. Их строка не является неизменной, как класс String - и фактически они могут порождать другой поток и пытаться атаковать ваш метод, изменяя аргумент после checkValidity, но перед тем, как вы фактически используете аргумент. Тогда ваша «полезная задача» вдруг делает что-то не так, возможно, ставит под угрозу безопасность. Они только что обошли ваши чеки! Поскольку java.lang.String является окончательным, у вас есть хорошие гарантии того, что когда вы запрашиваете параметр String, это, по сути, стандартная неизменяемая строка. Это довольно большое дело - был целый класс атак в режиме ядра, основанных на неправильной обработке параметров с помощью системных вызовов.
Так что да, у final могут быть некоторые соображения безопасности.