Почему мы объявляем Loggers статическим финалом? - PullRequest
114 голосов
/ 11 июля 2011

Почему в Java лучше всего объявлять регистратор static final?

private static final Logger S_LOGGER

Ответы [ 12 ]

191 голосов
/ 11 июля 2011
  • private - так что никакой другой класс не может угнать ваш логгер
  • static - поэтому для каждого класса существует только один экземпляр регистратора, что также позволяет избежать попыток сериализации регистраторов
  • final - нет необходимости менять регистратор в течение времени жизни класса

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

РЕДАКТИРОВАТЬ: Однако есть интересное исключение из этих правил:

protected final Logger log = LoggerFactory.getLogger(getClass());

вместо:

private static final Logger log = LoggerFactory.getLogger(Foo.class);

Первый способ позволяет использовать одно и то же имя регистратора (имя фактического класса) во всех классах по всей иерархии наследования. Так что если Bar удлиняет Foo, оба будут регистрироваться в Bar logger. Некоторые находят это более интуитивным.

11 голосов
/ 24 мая 2014

Проверьте это сообщение в блоге: Избавьтесь от статических регистраторов Java .Вот как вы используете slf4j с jcabi-log :

import com.jcabi.log.Logger;
class Foo {
  void save(File f) {
    Logger.info(this, "file %s saved successfully", f);
  }
}

И никогда больше не используете этот статический шум.

4 голосов
/ 11 июля 2011

static означает, что вы создаете только один регистратор на класс, а не один регистратор на экземпляр вашего класса.Как правило, это то, что вы хотите - поскольку регистраторы имеют тенденцию варьироваться исключительно в зависимости от класса.

final означает, что вы не собираетесь изменять значение loggerпеременная.Что верно, поскольку вы почти всегда выбрасываете все сообщения журнала (из одного класса) в один и тот же регистратор.Даже в тех редких случаях, когда классу может потребоваться отправить некоторые сообщения другому регистратору, было бы гораздо понятнее создать другую переменную регистратора (например, widgetDetailLogger), а не изменять значение статической переменной на лету.

3 голосов
/ 11 июля 2011

Чтобы ответить на этот вопрос, вы должны были спросить себя, для чего предназначены «статические» и «конечные».

Для регистратора (я полагаю, вы говорите о классе Log4J Logger) вам нужна категория для каждого класса,Что должно привести к тому, что вы назначаете его только один раз, и нет необходимости в более чем одном экземпляре на класс.И, по-видимому, нет причин выставлять объект Logger одного класса другому, поэтому не делайте его закрытым и не следуйте некоторым OO-принципам.

Также следует отметить, что компилятор может воспользоваться преимуществамитот.Так что ваш код работает немного лучше:)

3 голосов
/ 11 июля 2011

Обычно вы инициализируете регистратор для регистрации, используя имя класса - это означает, что если бы они не были статичными, вы в конечном итоге имели бы каждый экземпляр класса, имеющий экземпляр этого (большой объем памяти), но все эти регистраторы будут иметь одинаковую конфигурацию и вести себя точно так же. Вот причина, стоящая за битом static. Кроме того, поскольку каждый Logger инициализируется именем класса, чтобы предотвратить конфликты с подклассами, вы объявляете его private, поэтому он не может быть унаследован. final исходит из того, что вы обычно не меняете Logger во время выполнения - поэтому после инициализации вы никогда не «переконфигурируете» его - в этом случае имеет смысл сделать его окончательным, чтобы гарантировать отсутствие его можно изменить (по ошибке или иным образом). Конечно, если вы собираетесь использовать Logger по-другому, вам может понадобиться НЕ для использования static final - но я бы рискнул предположить, что 80% приложений будут использовать ведение журнала, как описано выше.

3 голосов
/ 11 июля 2011

Когда вы захотите изменить значение поля?

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

2 голосов
/ 24 сентября 2015

Этот код уязвим ,, но после Java7 мы можем использовать Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); вместо статического регистратора.

2 голосов
/ 11 июля 2011

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

2 голосов
/ 11 июля 2011

Потому что обычно это тот тип функциональности, который можно использовать во всех экземплярах ваших объектов.Не имеет смысла (в 90% случаев) иметь разные средства ведения журнала для двух экземпляров одного и того же класса.

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

1 голос
/ 11 февраля 2019

В идеале Logger должен быть следующим до Java 7, так как он не дает сонара и дает код соответствия: private: никогда не должен быть доступен вне родительского класса.Если другой класс должен что-то регистрировать, он должен создать свой собственный регистратор.static: не зависеть от экземпляра класса (объекта)При регистрации чего-либо в сообщениях, конечно же, может содержаться контекстная информация, но регистратор должен быть создан на уровне класса, чтобы предотвратить создание регистратора вместе с каждым объектом и, следовательно, предотвратить использование большого объема памяти.окончательный вариант: создается один раз и только один раз для каждого класса.

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