Должен ли я объявить поле Java 'final', если оно не изменено в коде? - PullRequest
15 голосов
/ 15 августа 2011

Мой вопрос в основном о производительности. Компилятор лучше знает, что, например, некоторая переменная НЕ модифицируется после создания объекта. Итак, зачем возиться с финалом?

Я предполагаю, что многие структурные / логические причины могут прийти сюда, но если говорить с точки зрения производительности? Имеет ли это значение?

Спасибо

Ответы [ 7 ]

20 голосов
/ 15 августа 2011

В современной JVM окончательная не должна влиять на производительность.Это особенно верно для закрытых полей, но даже для не закрытых полей JIT может оптимизировать неконечные поля, считая их окончательными, а затем деоптимизировать , если загружает некоторый код, который действительно изменяет поле.

Тем не менее, основная причина использования final - это не производительность, а то, чтобы сделать ваш код более понятным.Делая поля окончательными, вы сокращаете количество «движущихся частей», о которых читатели вашего кода должны думать, что значительно упрощает анализ кода.

8 голосов
/ 15 августа 2011

Я сомневаюсь, что это будет иметь значение с точки зрения производительности, но, тем не менее, это, вероятно, хорошая идея на тот случай, если вы (но, скорее всего, какой-то другой новый разработчик) позже попытаетесь изменить это поле в коде. Если вы пометите его как final, вы даже не сможете его скомпилировать.

7 голосов
/ 15 августа 2011

Использование final для поля также имеет значение для безопасности потока . Модель памяти Java утверждает, что значения полей final становятся видимыми для всех потоков, которые могут получить доступ к объекту, как только завершится конструктор этого объекта. Эта гарантия аналогична volatile полям, где любой поток всегда видит текущее значение. Для нормальных полей такой гарантии нет.

И, как уже отмечалось, JIT может выполнять агрессивную оптимизацию для полей final, что не так просто для обычных полей, где любой недавно загруженный класс может иметь доступ для записи в поле.

5 голосов
/ 15 августа 2011

Если поле отличается от private, JVM всегда должна быть готова к тому, что класс, с которым он еще не сталкивался, будет загружен и начнет его модифицировать.Таким образом, для этих полей возможно, что их явное объявление final позволит более сильную оптимизацию в JIT.Это может быть даже верно для закрытых полей, если JIT просматривает один метод за раз.

С другой стороны, final для локальных переменных не выдерживает компиляцию байт-кода и поэтому не должно иметь никаких эффектов производительности.

5 голосов
/ 15 августа 2011

final используется во время компиляции, чтобы принять или отклонить ваш исходный код как действительный. Это не должно иметь никаких последствий во время выполнения.

3 голосов
/ 15 августа 2011

Для локальных переменных конечный модификатор не сохраняется в байт-коде, поэтому не может быть разницы в производительности. Для полевого члена влияние на производительность является более сложным. Это может дать намёку подсказку, что поле не изменено, и позволить ему кэшировать значение в регистре. С другой стороны, final дает некоторые гарантии относительно видимости значения полей для других потоков, что может фактически замедлить построение объекта.

По производительности я думаю, что это микрооптимизация, эффект которой вряд ли можно измерить.

Я бы по-прежнему рекомендовал использовать final, когда это возможно, чтобы прояснить свои намерения перед коллегами и самим собой.

1 голос
/ 15 августа 2011

Использование final на самом деле не является подсказкой для компилятора или JIT.Это подсказка для вас самих или других разработчиков, поддерживающих код.Это ясно дает понять, что остальная часть кода класса предполагает, что это поле никогда не меняется, что может быть особенно важным (например, по соображениям корректности и / или безопасности потоков).Это также гарантирует, что подкласс не может изменить свое значение (если поле равно protected).

Например, hashCode объекта может быть кэширован, если все поля, участвующие в его значении, являются окончательными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...