Почему мы объявляем логгеры статическим финалом?



в Java, почему это лучшая практика, чтобы объявить логгер static final?



private static final Logger S_LOGGER
745   11  

11 ответов:

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

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

EDIT: однако есть интересное исключение из них правила:

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

против:

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

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

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

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

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

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

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

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

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

чтобы ответить на этот вопрос, вы должны были спросить себя, что такое "статический" и "окончательный".

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

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

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

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

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

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

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

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

...
public Logger logger = LoggerFactory.getLogger(DataSummary.class);

public String toJson() {
  GsonBuilder gsonBuilder = new GsonBuilder();   
  return gsonBuilder.create().toJsonTree(this).toString();
}
...

в некоторых случаях (когда я использовал библиотеку Gson) я бы получил исключение stackoverflow. Моя конкретная ситуация заключалась в создании экземпляра класса, содержащего нестатический не окончательный регистратор. Затем вызовите метод toJson, который вызвал GsonBuilder:

...
DataSummary ds = new DataSummary(data);    
System.out.println(ds.toJson());
...

вам все еще нужен статический регистратор для внутренних статических классов

Comments

    Ничего не найдено.