Почему мы объявляем статичные фишки Loggers? - программирование
Подтвердить что ты не робот

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

В Java, почему лучше всего объявить logger static final?

private static final Logger S_LOGGER
4b9b3361

Ответ 1

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

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

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

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

в отличие от:

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

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

Ответ 2

Отметьте это сообщение в блоге: Избавиться от Java Static Loggers. Так вы используете slf4j с jcabi-log:

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

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

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

...
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());
...