11 ответов:
private- Так что ни один другой класс не может журналы ваш логгерstatic- таким образом, существует только один экземпляр logger для каждого класса, также избегая попыток сериализации loggersfinal- нет необходимости менять регистратор в течение всего срока службы классакроме того, я предпочитаю имя
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