Почему в Java лучше всего объявлять регистратор static final
?
private static final Logger S_LOGGER
private
- чтобы никакой другой класс не мог захватить ваш регистраторstatic
- поэтому существует только один экземпляр регистратора на класс, что также позволяет избежать попыток сериализации регистраторовfinal
- нет необходимости менять логгер на протяжении жизни классаКроме того, я предпочитаю, log
чтобы имя было как можно более простым, но информативным.
РЕДАКТИРОВАТЬ: Однако из этих правил есть интересное исключение:
protected final Logger log = LoggerFactory.getLogger(getClass());
в отличие от:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
Первый способ позволяет вам использовать одно и то же имя регистратора (имя фактического класса) во всех классах в иерархии наследования. Итак, если Bar
расширяется Foo
, оба будут регистрироваться в Bar
регистраторе. Некоторым это кажется более интуитивным.
log
, чем разбрасывать кодLOG
. Просто вопрос разработчика. командное соглашение.Проверьте это сообщение в блоге: Избавьтесь от статических регистраторов Java . Вот как вы используете slf4j с jcabi-log :
И никогда больше не используйте этот статический шум.
источник
static
означает, что вы создаете только один регистратор для каждого класса, а не один регистратор для каждого экземпляра вашего класса. Как правило, это именно то, что вам нужно, поскольку регистраторы, как правило, различаются исключительно в зависимости от класса.final
означает, что вы не собираетесь изменять значениеlogger
переменной. Это правда, поскольку вы почти всегда отправляете все сообщения журнала (из одного класса) в один и тот же регистратор. Даже в тех редких случаях, когда классу может потребоваться отправить некоторые сообщения другому регистратору, было бы гораздо проще создать другую переменную регистратора (напримерwidgetDetailLogger
), чем изменять значение статической переменной на лету.источник
Когда вы хотите изменить значение поля?
Если вы никогда не собираетесь изменять значение, сделав поле final, станет очевидным, что вы никогда не измените значение.
источник
Обычно вы инициализируете регистратор для ведения журнала с использованием имени класса - это означает, что если бы они не были статическими, вы бы получили бы каждый экземпляр класса, имеющий его экземпляр (большой объем памяти), но все эти регистраторы будут использовать одну и ту же конфигурацию и вести себя одинаково. Это причина
static
биты. Кроме того, поскольку каждыйLogger
инициализируется именем класса, чтобы предотвратить конфликты с подклассами, вы объявляете его,private
чтобы он не мог быть унаследован. Этоfinal
происходит из-за того, что вы обычно не меняетеLogger
во время выполнения - поэтому после инициализации вы никогда не «повторно настраиваете» его - в этом случае имеет смысл сделать его окончательным, чтобы никто не мог его изменить ( ошибка или иначе). Конечно, если вы собираетесь использоватьLogger
по-другому, возможно, вам НЕ нужно использоватьstatic final
- но я рискну предположить, что 80% приложений будут использовать ведение журнала, как описано выше.источник
Чтобы ответить на этот вопрос, вы должны были спросить себя, для чего нужны «статика» и «финал».
Для регистратора (я полагаю, вы говорите о классе Log4J Logger) вам нужна категория для каждого класса. Это должно привести к тому, что вы назначаете его только один раз, и нет необходимости в более чем одном экземпляре для каждого класса. И, по-видимому, нет причин открывать объект Logger одного класса другому, так почему бы не сделать его частным и не следовать некоторым OO-принципам.
Также вы должны отметить, что компилятор может воспользоваться этим. Так что ваш код работает немного лучше :)
источник
Потому что обычно это тот вид функциональности, который можно использовать для всех экземпляров ваших объектов. Не имеет большого смысла (в 90% случаев) иметь разные средства ведения журнала для двух экземпляров одного и того же класса.
Однако вы также можете иногда видеть классы регистраторов, объявленные как одиночные или просто предлагающие статические функции для регистрации ваших данных.
источник
Этот код уязвим, но после Java7 мы можем использовать
Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
вместо статического регистратора.источник
This is code is vulnerable
Не могли бы вы немного уточнить ответ?В большинстве случаев вы не собираетесь изменять ссылку, и
final
модификатор отмечает ее. Вам не нужны отдельные экземпляры для каждого экземпляра класса - поэтомуstatic
. И в первую очередь это для производительности - ее можно красиво оптимизировать (окончательно) и сэкономить память (статика).источник
В идеале до Java 7 Logger должен быть таким, чтобы не давать Sonar и давать совместимый код: private: никогда не быть доступным за пределами своего родительского класса. Если другому классу нужно что-то регистрировать, он должен создать свой собственный регистратор. статический: не зависеть от экземпляра класса (объекта). При регистрации чего-либо контекстная информация, конечно, может быть предоставлена в сообщениях, но регистратор должен быть создан на уровне класса, чтобы предотвратить создание регистратора вместе с каждым объектом и, следовательно, предотвратить использование высокой памяти. final: создаваться один раз и только один раз для каждого класса.
источник
В дополнение к причинам, указанным в других ответах, я столкнулся с одной проблемой: если мой регистратор не был ни статическим, ни окончательным:
в некоторых случаях (когда я использовал библиотеку Gson) я получал исключение stackoverflow. Моя конкретная ситуация заключалась в создании экземпляра класса, содержащего нестатический не финальный регистратор. Затем вызовите метод toJson, который вызвал GsonBuilder:
источник
На самом деле статические регистраторы могут быть «вредными», поскольку они должны работать в статическом контексте. При наличии динамической среды, например. OSGi может помочь использовать нестатические регистраторы. Поскольку некоторые реализации ведения журнала выполняют кэширование средств ведения журнала внутренне (AFAIK, по крайней мере, log4j), влияние на производительность может быть незначительным.
Одним из недостатков статических регистраторов является, например. сборка мусора (когда класс используется только один раз, например, во время инициализации регистратор все еще сохраняется).
Для получения более подробной информации проверьте:
Смотрите также:
источник
Согласно информации, которую я прочитал из Интернета о том, чтобы сделать регистратор статическим или нет, лучше всего использовать его в соответствии с вариантами использования.
Есть два основных аргумента:
1) Когда вы делаете его статическим, это не сборщик мусора (использование памяти и производительность).
2) Когда вы не делаете его статическим, он создается для каждого экземпляра класса (использование памяти)
Таким образом, когда вы создаете регистратор для синглтона, вам не нужно делать его статическим. Потому что будет только один экземпляр, то есть один регистратор.
С другой стороны, если вы создаете регистратор для модели или класса сущности, вы должны сделать его статическим, чтобы не создавать дублированные регистраторы.
источник
Вам все еще нужен статический регистратор для внутренних статических классов
источник