Должен ли "статический финальный Logger" быть объявлен в UPPER-CASE?
В Java статические конечные переменные являются константами, и существует соглашение, что они должны быть в верхнем регистре. Тем не менее, я видел, что большинство людей объявляют регистраторы в нижнем регистре, что является нарушением PMD.
например:
private static final Logger logger = Logger.getLogger(MyClass.class);
Просто поищите в Google или SO для "static final logger", и вы сами это увидите.
Должны ли мы использовать LOGGER вместо этого?
10 ответов
Ссылка регистратора не является константой, а является окончательной ссылкой и НЕ должна быть в верхнем регистре. Постоянное значение должно быть в верхнем регистре.
private static final Logger logger = Logger.getLogger(MyClass.class);
private static final double MY_CONSTANT = 0.0;
Чтобы добавить больше пользы к ответу crunchdog, в Руководстве по стилю кодирования Java это указано в параграфе 3.3.
Имена полей, используемых в качестве констант, должны быть в верхнем регистре, с подчеркиванием, разделяющим слова. Следующие считаются постоянными:
- Все
static final
Примитивные типы (Помните, что все поля интерфейса по своей природеstatic final
).- Все
static final
ссылочные типы объектов, за которыми никогда не следует ".
" (точка).- Все
static final
массивы, которые никогда не следуют[
" (точка).Примеры:
MIN_VALUE, MAX_BUFFER_SIZE, OPTIONS_FILE_NAME
Следуя этой конвенции, logger
это static final
ссылка на объект, как указано в пункте 2, но потому, что за ней следует " .
"Каждый раз, когда вы используете его, он не может рассматриваться как константа и, следовательно, должен быть в нижнем регистре.
Из эффективной Java, 2-е изд.,
Единственное исключение из предыдущего правила касается "константных полей", имена которых должны состоять из одного или нескольких прописных слов, разделенных символом подчеркивания, например, VALUES или NEGATIVE_INFINITY. Постоянное поле - это статическое конечное поле, значение которого является неизменным. Если конечное статическое поле имеет примитивный тип или неизменяемый ссылочный тип (элемент 15), то оно является константным полем. Например, константы перечисления являются константными полями. Если статическое конечное поле имеет изменяемый ссылочный тип, оно все равно может быть постоянным полем, если указанный объект является неизменным.
Таким образом, константа == static final, плюс, если это ссылка (по сравнению с простым типом), неизменность.
Глядя на регистратор slf4j, http://www.slf4j.org/api/org/slf4j/Logger.html
Это неизменно. С другой стороны, регистратор JUL изменчив. Log4j logger также изменчив. Таким образом, чтобы быть правильным, если вы используете log4j или JUL, это должен быть "logger", а если вы используете slf4j, это должен быть LOGGER.
Обратите внимание, что на приведенной выше странице javadocs slf4j есть пример, в котором они используют "logger", а не "LOGGER".
Это, конечно, только условные обозначения, а не правила. Если вам случается использовать slf4j и вы хотите использовать "регистратор", потому что вы привыкли к этому из других платформ, или если его легче набирать, или для удобства чтения, продолжайте.
Мне нравится, что Google берет это ( стиль Google Java)
Каждая константа является статическим конечным полем, но не все статические конечные поля являются константами. Прежде чем выбрать постоянный регистр, подумайте, действительно ли поле ощущается как константа. Например, если какое-либо наблюдаемое состояние этого экземпляра может измениться, оно почти наверняка не является константой. Простого намерения никогда не мутировать объект обычно недостаточно.
Примеры:
// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }
// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};
Если вы используете автоматизированный инструмент для проверки ваших стандартов кодирования, и он нарушает указанные стандарты, то его или стандарты должны быть исправлены. Если вы используете внешний стандарт, исправьте код.
Соглашение в Sun Java прописно для открытых статических констант. Очевидно, что регистратор не является константой, но представляет изменяемую вещь (иначе не было бы смысла вызывать методы для него в надежде, что что-то случится); не существует определенного стандарта для непостоянных конечных полей.
Если вы воспользуетесь этим, вы можете обнаружить, что в некоторых случаях регистраторы не определяются как статические окончательные. Добавьте к этому немного быстрого копирования-и-вставки, и это может объяснить это.
Мы используем LOGGER во всем нашем коде, и это соответствует нашему соглашению об именах (и наш CheckStyle доволен этим).
Мы даже идем дальше, пользуясь строгим соглашением об именах в Eclipse. Мы создаем новый класс с шаблоном кода:
// private static final Logger LOGGER = Logger.getLogger(${enclosing_type}.class);
Регистратор закомментирован, так как изначально он нам не нужен. Но если это понадобится нам позже, мы просто раскомментируем это.
Затем в коде мы используем шаблоны кода, которые ожидают присутствия этого регистратора. Пример с шаблоном try-catch:
try {
${cursor} or some other template
} catch (Exception t) {
LOGGER.error("${methodName} ${method parameters}", t);
}
У нас есть еще несколько шаблонов, которые его используют.
Строгое соглашение позволяет нам быть более продуктивными и согласованными с шаблонами кода.
Лично я думаю, что это выглядит действительно большим в верхнем регистре. Более того, поскольку это класс, который не имеет прямого отношения к поведению класса, я не вижу большой проблемы в использовании logger
вместо LOGGER
, Но если вы собираетесь быть строго педантичным, то используйте LOGGER
,
Обычно константы в верхнем регистре.
Регистраторы, однако, не должны быть статичными, а должны искать каждый "новый" содержащий класс при использовании фасада slf4j. Это позволяет избежать некоторых неприятных проблем с загрузчиком классов, в частности, веб-контейнеров, а также позволяет каркасу ведения журналов выполнять специальные действия в зависимости от контекста вызова.
Не забывайте, что PMD будет уважать комментарий с
// NOPMD
в этом. Это заставит PMD пропустить строку из своих проверок, это позволит вам выбрать любой стиль, который вы хотите.
Я предпочитаю "регистратор", то есть строчные буквы. Причина не в том, что это константа или не константа (изменяемая или неизменяемая). Если бы мы использовали это рассуждение, нам пришлось бы переименовать переменную, если мы изменим структуру ведения журнала (или если структура изменит изменчивость регистраторов).
Для меня важнее другие причины.
Регистратор является теневым объектом в классе и не должен быть очень заметным, поскольку он не реализует основную логику. Если мы используем "LOGGER", это привлекает внимание в коде.
Иногда регистраторы объявляются на уровне экземпляра (т.е. не как статические) и даже вводятся как зависимость. Я бы не хотел менять свой код, если решу изменить способ получения регистратора. Стабильность кода относительно. это (во многих случаях гипотетическое) изменение - еще одна причина, по которой я предпочитаю строчные буквы.
Если ваши стандарты кодирования - если они есть - скажите, что они должны быть прописными, тогда да.
Я не вижу строгой причины для того или иного пути. Я думаю, что это полностью зависит от ваших личных симпатий, соответственно. стандарты кодирования вашей компании.
Кстати: я предпочитаю "LOGGER";-)