Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Static и Static Final


Автор: Рубильник 25.5.2018, 11:15
Для примитивных типов разница между 
public static final int ABC = 10;
и 
public static int ABC = 10;
понятна. В первом случае это константа на уровне кода, может быть вычислена до компиляции и до компиляции могут быть вычислены значения на её основе.

Но вот если мы сравним 
public static final MyClass ABC = Factory.create(5);
и 
public static MyClass ABC = Factory.create(5);
то в обоих случаях объект будет создан динамически, и первый вариант никаких преимуществ перед вторым не имеет. 

Или имеет?

Автор: AntonSaburov 25.5.2018, 12:03
Имеет - ссылку нельзя направить на ДРУГОЙ объект. Т.е. можно менять тот объект, на который указываtт final, но нельзя использовать другой.

Автор: Рубильник 25.5.2018, 12:41
Это скорее минус, чем плюс. Не static final можно оставить пустой, и инициализировать в любое время после создания класса. И не получить за это ExceptionInInitializerError, если классы имеют ссылки друг на друга.

Сделаю ударение в своем вопросе на слово "преимущество".
Т.е. будет ли в случае объектов static final лучше, чем просто static? Например, в плане производительности.

Автор: LSD 25.5.2018, 14:01
Цитата(Рубильник @  25.5.2018,  13:41 Найти цитируемый пост)
Это скорее минус, чем плюс.

Это не минус и не плюс, это особенность - значение поля final после инициализации менять нельзя.
С константами времени компиляции тут связь не прямая. Например:
Код

String s = "foo" + 1;

Выражение присваиваемое s это тоже константа времени компиляции и будет вычислена во время компиляции.


Цитата(Рубильник @  25.5.2018,  13:41 Найти цитируемый пост)
Т.е. будет ли в случае объектов static final лучше, чем просто static? Например, в плане производительности.

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

Если это не константа времени компиляции, то скорее всего разницу в производительности заметить не удастся. У тебя в любом случае идет обращение к объекту. Зашить в сгенерированный код адрес этого объекта для случая static final - нельзя, т.к. объект может перемещаться GC. Т.е. в любом случае будет чтение поля, затем доступ к объекту.
Есть оптимизации связанные с девиртуализацией вызовов методов и инлайнингом, но тут JIT умеет делать спекулятивные оптимизации. С другой стороны есть куча вещей которые могут помешать JIT в этом.
В целом специально делать все static final для перфоманса не стоит. Да и вообще перфоманс это про измерения и анализ, а не про какие-то шаблоны при написании кода.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)