Я нашел пару ссылок ( например ), которые предлагают использовать final
как можно больше, и мне интересно, насколько это важно. Это в основном в контексте параметров методов и локальных переменных, а не конечных методов или классов. Для констант это имеет очевидный смысл.
С одной стороны, компилятор может сделать некоторые оптимизации, и это делает намерение программиста более ясным. С другой стороны, это добавляет многословие, и оптимизация может быть тривиальной.
Это то, что я должен попытаться вспомнить?
Ответы:
Одержимость над:
Рассмотрите, но используйте разумно:
Проигнорируйте, если не чувствуете анальный
Параметры метода и локальные переменные - я редко делаю это в основном потому, что я ленив и нахожу, что это загромождает код. Я полностью признаю, что маркировка параметров и локальных переменных, которые я не собираюсь изменять, является «правильной». Я хотел бы, чтобы это было по умолчанию. Но это не так, и я нахожу код более сложным для понимания во всех финалах. Если я нахожусь в чужом коде, я не собираюсь их извлекать, но если я пишу новый код, я не вставлю их. Единственным исключением является случай, когда вам нужно пометить что-то окончательное, чтобы вы могли получить доступ это изнутри анонимного внутреннего класса.
Редактировать: обратите внимание, что один случай использования, когда конечные локальные переменные на самом деле очень полезны, как упомянуто @ adam-gent, - это когда значение присваивается переменной в ветвях
if
/else
.источник
final
по умолчанию. Вы можете не заметить преимущества, если не используете действительно современную Java IDE (то есть IDEA).final
классах / методах. Например, если последний метод объявляет, что выбрасывает проверенное исключение, но никогда не выдает его, IDEA сообщит вам об этом, и вы можете удалить исключение изthrows
предложения. Иногда вы также можете найти целые методы, которые не используются, что можно обнаружить, если их нельзя переопределить.Нет, если вы используете Eclipse, потому что вы можете настроить действие сохранения, чтобы автоматически добавлять эти окончательные модификаторы для вас. Тогда вы получаете преимущества за меньшие усилия.
источник
Преимущества «final» во время разработки по меньшей мере так же значительны, как и преимущества времени выполнения. Он рассказывает будущим редакторам кода о ваших намерениях.
Пометка класса "final" означает, что вы не приложили усилий при разработке или реализации класса для изящной обработки расширения. Если читатели могут вносить изменения в класс и хотят удалить модификатор «final», они могут сделать это на свой страх и риск. Они сами должны убедиться, что класс хорошо справится с расширением.
Маркировка переменной "final" (и присвоение ее в конструкторе) полезна для внедрения зависимостей. Это указывает на «коллаборационную» природу переменной.
Маркировка метода «final» полезна в абстрактных классах. Он четко определяет, где находятся точки расширения.
источник
Я использую
final
все время, чтобы сделать Java более выразительным. Видите, условия Java (if,else,switch
) не основаны на выражениях, которые я всегда ненавидел, особенно если вы привыкли к функциональному программированию (например, ML, Scala или Lisp).Таким образом, вы должны стараться всегда (ИМХО) использовать конечные переменные при использовании условий.
Позвольте мне привести Вам пример:
Теперь, если добавить еще один
case
оператор и не устанавливать,name
компилятор не удастся. Компилятор также потерпит неудачу, если вы не нарушите каждый случай (если вы установили переменную). Это позволяет вам сделать Java очень похожим наlet
выражения Lisp и делает так, чтобы ваш код не имел больших отступов (из-за лексических переменных области видимости).И, как заметил @Recurse (но, по-видимому, -1 ме), вы можете сделать предыдущее без создания
String name
final
ошибки, чтобы получить ошибку компилятора (которую я никогда не говорил, что вы не можете), но вы можете легко заставить ошибку компилятора исчезнуть после установки имени параметра оператор, который отбрасывает семантику выражения или, что еще хуже, забывая,break
что нельзя вызвать ошибку (несмотря на то, что говорит @Recurse) без использованияfinal
:Из-за имени настройки ошибки (помимо того, что я забыл
break
еще одну ошибку) я теперь могу случайно сделать это:Последняя переменная требует единственной оценки того, какое имя должно быть. Подобно тому, как функция, имеющая возвращаемое значение, всегда должна возвращать значение (игнорируя исключения), блок переключателя имени должен будет разрешать имя и, таким образом, привязываться к этому блоку переключателя, что упрощает рефакторинг кусков кода (т.е. Eclipe refactor: метод extract) ,
Выше в OCaml:
В
match ... with ...
оценивает как функция , т.е. выражения. Обратите внимание, как выглядит наш оператор switch.Вот пример в Схеме (Ракетка или Цыпленок):
источник
else if (...)
вif(...)
и, таким образом, сбросил переменную. Я показал ему, что никогда бы не случилось с окончательной переменной. В основномfinal
вынуждает вас назначать переменную один раз и только один раз ... так: PЯ нашел параметры метода маркировки и локальные параметры, которые
final
полезны в качестве помощи при рефакторинге, когда рассматриваемый метод представляет собой непонятный беспорядок длиной в несколько страниц. Обильноfinal
посыпайте, посмотрите, какие ошибки «не может быть назначено конечной переменной» выдает компилятор (или ваша IDE), и вы можете просто узнать, почему переменная с именем «data» обнуляется, даже если несколько (устаревших) комментариев клянутся, что могут не бываетЗатем вы можете исправить некоторые ошибки, заменив повторно используемые переменные новыми переменными, объявленными ближе к месту использования. Затем вы обнаружите, что можете заключить целые части метода в фигурные скобки, и внезапно вы оказались на расстоянии одного нажатия IDE от «Извлечь метод», и ваш монстр стал более понятным.
Если ваш метод уже не является неисправимым, я полагаю, что было бы целесообразно сделать материал окончательным, чтобы не дать людям превратить его в указанное крушение; но если это короткий метод (см .: не несущественный), то вы рискуете добавить много подробностей. В частности, сигнатуры Java-функций достаточно сложны, чтобы уместиться в 80 символов, без добавления еще шести на аргумент!
источник
final
каждого параметра.Ну, это все зависит от вашего стиля ... если вам нравится видеть финал, когда вы не будете изменять переменную, используйте его. Если вам НЕ НРАВИТСЯ видеть это ... тогда оставьте это.
Мне лично нравится как можно меньше подробностей, поэтому я стараюсь избегать использования лишних ключевых слов, которые на самом деле не нужны.
Хотя я предпочитаю динамические языки, поэтому неудивительно, что мне нравится избегать многословия.
Итак, я бы сказал, просто выберите направление, к которому вы склоняетесь, и просто следуйте ему (в любом случае, старайтесь быть последовательным).
Как примечание, я работал над проектами, которые используют и не используют такой шаблон, и я не видел никакой разницы в количестве ошибок или ошибок ... Я не думаю, что это шаблон, который будет чрезвычайно улучшить количество ошибок или что-то в этом роде, но, опять же, это стиль, и если вам нравится выражать намерение, что вы не будете изменять его, тогда используйте его.
источник
Это полезно в параметрах, чтобы избежать случайного изменения значения параметра и внести небольшую ошибку. Я использую, чтобы игнорировать эту рекомендацию, но потратив около 4 часов. в ужасном методе (с сотнями строк кода и несколькими форсами, вложенными if и всеми видами плохих практик) я бы порекомендовал вам сделать это.
Конечно, в идеальном мире этого не произойдет, но ... ну ... иногда вам приходится поддерживать чужой код. :(
источник
Если вы пишете приложение, в котором кто-то должен будет прочитать код, скажем, через 1 год, тогда да, используйте final для переменной, которую не следует изменять постоянно. Делая это, ваш код будет более «самодокументируемым», и вы также уменьшите шансы других разработчиков на глупые вещи, такие как использование локальной константы в качестве локальной временной переменной.
Если вы пишете какой-то одноразовый код, то нет, не пытайтесь идентифицировать все константы и сделать их окончательными.
источник
Я буду использовать final столько, сколько смогу. Это будет помечено, если вы непреднамеренно измените поле. Я также установил параметры метода в финал. При этом я обнаружил несколько ошибок в коде, который я взял на себя, когда они пытаются «установить» параметр, забывая про передачу Java по значению.
источник
Не ясно из вопроса, является ли это очевидным, но окончательный параметр метода влияет только на тело метода. Он НЕ передает интересную информацию о намерениях метода для вызывающего. Передаваемый объект все еще может быть видоизменен внутри метода (финал не является концом), а область действия переменной находится внутри метода.
Чтобы ответить на ваш точный вопрос, я не потрудился бы сделать экземпляр или локальную переменную (включая параметры метода) окончательными, если бы код не требовал этого (например, на переменную ссылаются из внутреннего класса), или чтобы прояснить некоторую действительно сложную логику.
Для переменных экземпляра я бы сделал их окончательными, если они логически постоянны.
источник
Существует много вариантов использования переменной
final
. Здесь только несколькоКонечные Константы
Это может быть использовано затем для других частей вашего кода или для доступа других классов, таким образом, если вы когда-либо измените значение, вам не придется менять их один за другим.
Конечные переменные
В этом классе вы создаете конечную переменную с заданной областью действия, которая добавляет префикс к параметру environmentKey. В этом случае конечная переменная является конечной только в пределах области выполнения, которая отличается при каждом выполнении метода. Каждый раз, когда метод вводится, финал восстанавливается. Как только он создан, он не может быть изменен во время выполнения метода. Это позволяет вам зафиксировать переменную в методе на время действия метода. увидеть ниже:
Конечные Константы
Они особенно полезны, когда у вас действительно длинные строки кода, и это сгенерирует ошибку компилятора, поэтому вы не столкнетесь с логической / бизнес-ошибкой, когда кто-то случайно изменяет переменные, которые не должны быть изменены.
Финальные Коллекции
Другой случай, когда мы говорим о коллекциях, вы должны установить их как неизменяемые.
в противном случае, если вы не установите его как неизменяемый:
Финальные классы и Финальные методы не могут быть соответственно расширены или перезаписаны.
РЕДАКТИРОВАТЬ: РАССМОТРЕТЬ ЗАКЛЮЧИТЕЛЬНУЮ ПРОБЛЕМУ КЛАССА ОТНОСИТЕЛЬНО ЭНКАПУЛЯЦИИ
Есть два способа сделать урок финальным. Первый - использовать ключевое слово final в объявлении класса:
Второй способ сделать класс final - объявить все его конструкторы как частные:
Отметив его как финальный, вы избавитесь от проблем, если узнаете, что это действительно финал, чтобы продемонстрировать взгляд на этот тестовый класс. выглядит публично на первый взгляд.
К сожалению, поскольку единственный конструктор класса является закрытым, расширить этот класс невозможно. В случае с классом Test нет причин, по которым этот класс должен быть окончательным. Класс Test является хорошим примером того, как неявные конечные классы могут вызывать проблемы.
Поэтому вы должны пометить его как финальный, когда вы неявно делаете класс финальным, делая его конструктор закрытым.
источник
Как вы упомянули, это немного компромисс, но я предпочитаю явное использование чего-то, а не неявное использование. Это поможет устранить некоторую неопределенность для будущих разработчиков кода - даже если это только вы.
источник
Если у вас есть внутренние (анонимные) классы, и для метода требуется доступ к переменной содержащего метода, эта переменная должна быть финальной.
Кроме того, то, что вы сказали, правильно.
источник
Используйте
final
ключевое слово для переменной, если вы делаете эту переменную какimmutable
Объявляя переменную как final, она помогает разработчикам исключить возможные проблемы модификации переменных в многопоточной среде.
С выпуском java 8 у нас появилась еще одна концепция под названием "
effectively final variable
". Неокончательная переменная может превращаться в конечную переменную.локальные переменные, на которые ссылается лямбда-выражение, должны быть окончательными или эффективно окончательными
До Java 7 вы не можете использовать не окончательную локальную переменную внутри анонимного класса, но из Java 8 вы можете
Посмотрите на эту статью
источник
Прежде всего, последнее ключевое слово используется, чтобы сделать переменную постоянной. Постоянная означает, что она не меняется. Например:
Вы бы объявили переменную final, потому что сантиметр на дюйм не изменяется.
Если вы попытаетесь переопределить конечное значение, переменная будет объявлена первой. Например:
Ошибка компиляции выглядит примерно так:
Если ваша переменная не может быть объявлена финальной или вы не хотите объявлять ее финальной, попробуйте следующее:
Это напечатает:
источник