Я использовал PMD, чтобы помочь выявить потенциальные проблемы в моем Java-коде, и я нашел его совет, который можно разделить между полезным, своеобразным и "WTF" ?! ".
Одна из вещей, которые он постоянно повторяет, - это использовать ключевое слово final
для буквально каждой переменной, к которой я могу присоединить его, включая входные параметры. Для фактических констант это кажется разумным, но для других вещей это просто кажется мне странным, возможно, даже немного контрпродуктивным.
Есть ли конкретные преимущества / недостатки для повешения final
на каждом объявлении переменной, которое вы возможно можете?
«Любое объявление переменной, которое вы можете» звучит немного экстремально, но final
на самом деле полезен во многих отношениях. Иногда мне хочется, чтобы final
был поведением по умолчанию и не требовал ключевого слова, но для истинных «переменных» требовался модификатор variable
. Scala применила что-то вроде этого подхода с ключевыми словами val
и var
, при этом настоятельно рекомендуется использовать val
(ключевое слово final
).
Особенно важно тщательно продумать, является ли каждая переменная-член final
, изменчивой
или ни одной из них, потому что от этого зависит безопасность потоков класса. Значения, присвоенные переменным final
и volatile
, всегда видны другим потокам, без использования блока synchronized
.
Для локальных переменных это не так критично, но использование final
может помочь вам более четко рассуждать о вашем коде и избежать некоторых ошибок. Если вы не ожидаете, что значение изменится внутри метода, скажите об этом с помощью final
, и пусть компилятор обнаружит незаметные нарушения этого ожидания. В настоящее время я не знаю ни одного из них, но легко предположить, что JIT-компилятор мог бы использовать эту подсказку для повышения производительности.
На практике я не объявляю локальные переменные final
, когда мог. Мне не нравится визуальный беспорядок, и он кажется громоздким.Но это не значит, что я не должен делать это.
Было внесено предложение добавить ключевое слово var
в Java для поддержки вывода типов. Но в рамках этого предложения был внесен ряд предложений по дополнительным способам определения неизменяемости локальной переменной. Например, было предложено добавить ключевое слово val
для объявления неизменяемой переменной с предполагаемым типом. В качестве альтернативы некоторые сторонники использования final
и var
вместе.
Это обычная идиома для таких инструментов, как PMD. Например, ниже приведены соответствующие правила в Checkstyle. Это действительно вопрос стиля / предпочтений, и вы можете возразить за обе стороны.
На мой взгляд, использование final для параметров метода и локальных переменных (если применимо) является хорошим стилем. Идиома «дизайн для расширения» спорна.
final сообщает читателю, что значение или ссылка, назначенная первой, остается той же в любой момент позже.
Поскольку все, что МОЖЕТ быть final, ЯВЛЯЕТСЯ окончательным в этом сценарии, отсутствующий final сообщает читателю, что значение будет изменено позже, и принять это во внимание.
PMD также имеет правила опций, которые вы можете включить, которые жалуются на финал
; это произвольное правило.
Если я делаю проект, в котором API экспортируется в другую команду или в мир, оставьте правило PMD в его нынешнем виде. Если вы просто разрабатываете что-то, что навсегда останется закрытым API, отключите правило и сэкономьте себе время.