Почему в Java лучше всего объявлять регистратор static final?
private static final Logger S_LOGGER
Почему в 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 :
import com.jcabi.log.Logger;
class Foo {
void save(File f) {
Logger.info(this, "file %s saved successfully", f);
}
}
И никогда больше не используйте этот статический шум.
staticозначает, что вы создаете только один регистратор для каждого класса, а не один регистратор для каждого экземпляра вашего класса. Как правило, это именно то, что вам нужно, поскольку регистраторы, как правило, различаются исключительно в зависимости от класса.
finalозначает, что вы не собираетесь изменять значение loggerпеременной. Это правда, поскольку вы почти всегда отправляете все сообщения журнала (из одного класса) в один и тот же регистратор. Даже в тех редких случаях, когда классу может потребоваться отправить некоторые сообщения другому регистратору, было бы гораздо проще создать другую переменную регистратора (например widgetDetailLogger), чем изменять значение статической переменной на лету.
Когда вы хотите изменить значение поля?
Если вы никогда не собираетесь изменять значение, сделав поле final, станет очевидным, что вы никогда не измените значение.
Обычно вы инициализируете регистратор для ведения журнала с использованием имени класса - это означает, что если бы они не были статическими, вы бы получили бы каждый экземпляр класса, имеющий его экземпляр (большой объем памяти), но все эти регистраторы будут использовать одну и ту же конфигурацию и вести себя одинаково. Это причина staticбиты. Кроме того, поскольку каждый Loggerинициализируется именем класса, чтобы предотвратить конфликты с подклассами, вы объявляете его, privateчтобы он не мог быть унаследован. Это finalпроисходит из-за того, что вы обычно не меняете Loggerво время выполнения - поэтому после инициализации вы никогда не «повторно настраиваете» его - в этом случае имеет смысл сделать его окончательным, чтобы никто не мог его изменить ( ошибка или иначе). Конечно, если вы собираетесь использоватьLoggerпо-другому, возможно, вам НЕ нужно использовать static final- но я рискну предположить, что 80% приложений будут использовать ведение журнала, как описано выше.
Чтобы ответить на этот вопрос, вы должны были спросить себя, для чего нужны «статика» и «финал».
Для регистратора (я полагаю, вы говорите о классе Log4J Logger) вам нужна категория для каждого класса. Это должно привести к тому, что вы назначаете его только один раз, и нет необходимости в более чем одном экземпляре для каждого класса. И, по-видимому, нет причин открывать объект Logger одного класса другому, так почему бы не сделать его частным и не следовать некоторым OO-принципам.
Также вы должны отметить, что компилятор может воспользоваться этим. Так что ваш код работает немного лучше :)
Потому что обычно это тот вид функциональности, который можно использовать для всех экземпляров ваших объектов. Не имеет большого смысла (в 90% случаев) иметь разные средства ведения журнала для двух экземпляров одного и того же класса.
Однако вы также можете иногда видеть классы регистраторов, объявленные как одиночные или просто предлагающие статические функции для регистрации ваших данных.
В большинстве случаев вы не собираетесь изменять ссылку, и finalмодификатор отмечает ее. Вам не нужны отдельные экземпляры для каждого экземпляра класса - поэтому static. И в первую очередь это для производительности - ее можно красиво оптимизировать (окончательно) и сэкономить память (статика).
В идеале до Java 7 Logger должен быть таким, чтобы не давать Sonar и давать совместимый код: private: никогда не быть доступным за пределами своего родительского класса. Если другому классу нужно что-то регистрировать, он должен создать свой собственный регистратор. статический: не зависеть от экземпляра класса (объекта). При регистрации чего-либо контекстная информация, конечно, может быть предоставлена в сообщениях, но регистратор должен быть создан на уровне класса, чтобы предотвратить создание регистратора вместе с каждым объектом и, следовательно, предотвратить использование высокой памяти. final: создаваться один раз и только один раз для каждого класса.
В дополнение к причинам, указанным в других ответах, я столкнулся с одной проблемой: если мой регистратор не был ни статическим, ни окончательным:
...
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());
...
На самом деле статические регистраторы могут быть «вредными», поскольку они должны работать в статическом контексте. При наличии динамической среды, например. OSGi может помочь использовать нестатические регистраторы. Поскольку некоторые реализации ведения журнала выполняют кэширование средств ведения журнала внутренне (AFAIK, по крайней мере, log4j), влияние на производительность может быть незначительным.
Одним из недостатков статических регистраторов является, например. сборка мусора (когда класс используется только один раз, например, во время инициализации регистратор все еще сохраняется).
Для получения более подробной информации проверьте:
Смотрите также:
Согласно информации, которую я прочитал из Интернета о том, чтобы сделать регистратор статическим или нет, лучше всего использовать его в соответствии с вариантами использования.
Есть два основных аргумента:
1) Когда вы делаете его статическим, это не сборщик мусора (использование памяти и производительность).
2) Когда вы не делаете его статическим, он создается для каждого экземпляра класса (использование памяти)
Таким образом, когда вы создаете регистратор для синглтона, вам не нужно делать его статическим. Потому что будет только один экземпляр, то есть один регистратор.
С другой стороны, если вы создаете регистратор для модели или класса сущности, вы должны сделать его статическим, чтобы не создавать дублированные регистраторы.