Лучшая практика: статические не окончательные переменные Java

В Java, когда следует использовать статические не окончательные переменные?

Например

private static int MY_VAR = 0;

Очевидно, что мы не говорим здесь о константах.

public static final int MY_CONSTANT = 1;

По моему опыту, я часто оправдывал их при использовании синглтона, но тогда мне нужно было иметь более одного экземпляра, что вызывало у меня большую головную боль и рефакторинг.

Кажется, что они редко должны использоваться на практике. Что вы думаете?


person James Van Boxtel    schedule 08.04.2009    source источник


Ответы (7)


При сборе статистики могут использоваться неконечные переменные, например. для подсчета количества созданных экземпляров. С другой стороны, для такой ситуации вы, вероятно, все равно захотите использовать AtomicLong и т. д., и в этот момент это может быть окончательным. В качестве альтернативы, если вы собираете более одной статистики, вы можете получить класс Statistics и окончательную ссылку на его экземпляр.

Конечно, довольно редко (оправданно) иметь не окончательные статические переменные.

person Jon Skeet    schedule 08.04.2009
comment
+1, но используйте Atomics. Учитывая, что он статичен, предположим, что к нему будут обращаться несколько потоков. - person Jason Cohen; 08.04.2009

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

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

Некоторые языки, такие как Fan, полностью запрещают изменяемую статику (или эквивалентную).

person Tom Hawtin - tackline    schedule 08.04.2009

По моему опыту, статические переменные non-final следует использовать только для одноэлементных экземпляров. Все остальное может быть либо более аккуратно включено в синглтон (например, кеш), либо сделано окончательным (например, ссылка на регистратор). Однако я не верю в жесткие и быстрые правила, поэтому я бы воспринял свой совет с долей скептицизма. Тем не менее, я бы предложил тщательно изучить любой случай, когда вы рассматриваете возможность объявления неконечной статической переменной помимо экземпляра синглтона, и посмотреть, можно ли ее реорганизовать или реализовать по-другому, т.е. переместить в контейнер синглтона или использовать окончательную ссылку на изменяемый объект. объект.

person Chris B.    schedule 08.04.2009

Статические переменные можно использовать для управления поведением на уровне приложения, например, для указания глобального уровня ведения журнала, сервера для подключения.

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

В настоящее время использование статических переменных для таких целей, очевидно, является плохой практикой, но это не было так очевидно, скажем, в 1999 году. Ни Spring, ни log4j, ни Clean code от R.C.Martin и т.д.

Язык Java сейчас довольно стар, и даже если какая-то функция сейчас сильно не рекомендуется, она часто использовалась в начале. А из-за обратной совместимости вряд ли изменится.

person Danubian Sailor    schedule 07.03.2013

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

person Uri    schedule 08.04.2009

Статическая переменная означает, что она доступна для класса в целом, поэтому оба примера доступны для класса в целом. Final означает, что значение не может быть изменено. Итак, я думаю, вопрос в том, когда вы хотите, чтобы значение было доступно для всего класса, и его нельзя изменить после того, как оно было создано. Я предполагаю, что константа будет доступна для всех экземпляров этого класса. В противном случае, если вам нужно что-то вроде счетчика населения, тогда неконечная переменная.

person uriDium    schedule 09.04.2009

Лично для неконечных переменных класса я использую нотацию CamelCase. Из кода ясно, что это переменная класса, поскольку вы должны ссылаться на нее как таковую: FooBar.bDoNotRunTests.

В этой заметке я добавляю к переменным экземпляра класса префикс this, чтобы отличить их от переменных локальной области видимости. бывший. this.bDoNotRunTests.

person Daniel Sokolowski    schedule 23.10.2017