279

In Java, static final variables are constants and the convention is that they should be in upper-case. However, I have seen that most people declare loggers in lower-case which comes up as a violation in PMD.

e.g:

private static final Logger logger = Logger.getLogger(MyClass.class);

Just search googleor SO for "static final logger" and you will see this for yourself.

Should we be using LOGGER instead?

Community
  • 1
  • 1
dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 1
    PMD or Checkstyle are pre-mature naive attempts to increase readability but they cause more harm than benefit. A most readable style can change case by case based on the context. See Guava, or the JDK src, those does not follow any strict style template, but made by professionals it's unquestionable. example: DelegatedExecutorService @ docjar.com/html/api/java/util/concurrent/Executors.java.html – Daniel Hári Mar 18 '17 at 20:48
  • Sonar Rules (https://rules.sonarsource.com/java/tag/convention/RSPEC-1312) also has it as `private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);` – Kenston Choi Jan 06 '20 at 05:00

11 Answers11

353

The logger reference is not a constant, but a final reference, and should NOT be in uppercase. A constant VALUE should be in uppercase.

private static final Logger logger = Logger.getLogger(MyClass.class);

private static final double MY_CONSTANT = 0.0;
crunchdog
  • 13,078
  • 3
  • 23
  • 19
  • 53
    static final references are constants if they are immutable. by this logic, you would never have constant strings because any static final string is a reference. – Jeffrey Blattman Jan 25 '13 at 04:04
  • 34
    But java.lang.String **is** immutable and a special kind of class anyway (see String.intern(), documentation about the Sring pool etc.) – Aleksander Adamowski Feb 13 '13 at 10:55
  • 4
    immutable means the state of the object cannot change after construction. see my post below. loggers are not necessarily mutable. – Jeffrey Blattman Feb 26 '13 at 19:46
  • 4
    if somebody still care about this problem, please share ideas at https://github.com/checkstyle/checkstyle/issues/23, to distinguish where demand upper case and where not. – Roman Ivanov Oct 18 '13 at 23:16
  • @JeffreyBlattman Does immutable really mean the internal state of the object cannot change or that the user may not alter the state? Those are two very distinct notions. – Jeach Mar 13 '14 at 16:58
  • 2
    @Jeach i don't think immutability is concerned with how the state changes, only that it does. moreover, what's a user? the external user running the program? would you make a distinction between state being modified by a user pressing a button, and it being modified by a timer firing at some random interval? (i don't think so). – Jeffrey Blattman Mar 13 '14 at 20:59
  • @RomanIvanov The CheckStyle check on this drives me nuts. Yes I will do that. See this [post](http://stackoverflow.com/questions/27451395/resolve-java-checkstyle-error-name-logger-must-match-pattern-a-za-z0-9) – javaPlease42 Jan 27 '15 at 19:44
  • @javaPlease42 , yes you are right , Checkstyle need to handle that please open issue on Checkstyle's issue tracker, please reference a text from answer below to prove that Constant definition is not that simple. – Roman Ivanov Feb 03 '15 at 18:34
  • 2
    We had similar debate at work. This thread helped to put some clarity on the issue but I also used the following example to make a case for an exception to the people who were proponent of upper case. Does anyone know why java has `serialVersionUID` as opposed to `SERIAL_VERSION_UID`? `private static final long serialVersionUID = 201208271956L;` – Chetan Narsude Jul 25 '15 at 03:20
279

To add more value to crunchdog's answer, The Java Coding Style Guide states this in paragraph 3.3 Field Naming

Names of fields being used as constants should be all upper-case, with underscores separating words. The following are considered to be constants:

  1. All static final primitive types (Remember that all interface fields are inherently static final).
  2. All static final object reference types that are never followed by "." (dot).
  3. All static final arrays that are never followed by "[" (opening square bracket).

Examples:

MIN_VALUE, MAX_BUFFER_SIZE, OPTIONS_FILE_NAME

Following this convention, logger is a static final object reference as stated in point 2, but because it is followed by "." everytime you use it, it can not be considered as a constant and thus should be lower case.

jeuxjeux20
  • 391
  • 1
  • 6
  • 20
cbliard
  • 7,051
  • 5
  • 41
  • 47
  • 12
    Best definition I've seen for this yet. Linked doc seems to have moved here's the update http://www.cs.bilgi.edu.tr/pages/standards_project/java_CodingStyle.pdf#page7 – robert Nov 04 '12 at 19:28
  • 20
    I don't get point 2. What is an example of an object type that is never followed by a dot. All object types inherit from `Object` and you can call a method such as `.equals` on them. – dogbane Mar 19 '13 at 15:00
  • 7
    You are right. And when looking at some Java constants like Boolean.TRUE, Boolean.FALSE, TimeUnit.MINUTES, String.CASE_INSENSITIVE_ORDER or Collections.EMPTY_LIST, they may be followed by `.` as well. – cbliard Mar 29 '13 at 16:29
  • Does anybody have "Java Coding Style Guide" stored locally? Looks like it was removed from internet resources. Please share document,as we try add support of it in Checkstyle https://github.com/checkstyle/checkstyle/issues/23. – Roman Ivanov Oct 18 '13 at 23:12
  • 5
    @RomanIvanov I found it again here: http://www.scribd.com/doc/15884743/Java-Coding-Style-by-Achut-Reddy written by Achut Reddy, last update May 30, 2000 – cbliard Oct 21 '13 at 07:21
  • 1
    I believe the purpose of 2 is to designate that only classes that are meant to be compared to are considered constants. The class is not meant to be 'used'. I know always cringe when I see SOME_CLASS.doStuff(). It's just fugly coding. The only problem with this is in the common case of a constant object (String being the common example) which is only meant for comparison, but to avoid null checks, yoda style coding is used and thus equals() is called on the constant. I think I would make this the one caveat to 2. – Robin Dec 07 '13 at 14:58
  • 1
    While this answer appears to be getting at static final immutable references, it totally misses the mark (esp. with #2). As mentioned in the comments above, ANY non-primitive value can be followed by a dot. – Mark Mar 10 '16 at 21:44
  • 2
    That's not the point. The point is that you shouldn't be doing anything to the stored object reference. That means using a `Logger` object (e.g. `log.info(...)`) is a violation of rule 2 since `log` is followed by a dot within that invocation. Since you can't mark methods as `const` like you can in C++, it's assumed all methods mutate the object and thus are not constants. – Qix - MONICA WAS MISTREATED Nov 01 '16 at 20:07
  • Simple, objective and makes sense most of the time. This may not be a perfect convention but imo it's the best solution! – Marvin Jan 24 '17 at 20:43
50

From effective java, 2nd ed.,

The sole exception to the previous rule concerns “constant fields,” whose names should consist of one or more uppercase words separated by the underscore character, for example, VALUES or NEGATIVE_INFINITY. A constant field is a static final field whose value is immutable. If a static final field has a primitive type or an immutable reference type (Item 15), then it is a constant field. For example, enum constants are constant fields. If a static final field has a mutable reference type, it can still be a constant field if the referenced object is immutable.

In summary, constant == static final, plus if it's a reference (vs. a simple type), immutability.

Looking at the slf4j logger, http://www.slf4j.org/api/org/slf4j/Logger.html

It is immutable. On the other hand, the JUL logger is mutable. The log4j logger is also mutable. So to be correct, if you are using log4j or JUL, it should be "logger", and if you are using slf4j, it should be LOGGER.

Note that the slf4j javadocs page linked above has an example where they use "logger", not "LOGGER".

These are of course only conventions and not rules. If you happen to be using slf4j and you want to use "logger" because you are used to that from other frameworks, or if it is easier to type, or for readability, go ahead.

Jeffrey Blattman
  • 22,176
  • 9
  • 79
  • 134
  • 2
    Based on this reasoning then checkstyle's simplistic definition is inappropriate right? – robert Nov 04 '12 at 19:18
  • 3
    i don't know check style's rules. if it's simply insisting that any static final should be upper-case, then yes, that's wrong. – Jeffrey Blattman Nov 05 '12 at 17:23
  • 8
    How exactly is the `Logger` **interface** *immutable*? Only a `final class` (like `String` or `Integer`) can guarantee immutability. Even if you can't find any mutable implementation of the SLF4J `Logger`, no one can stop you from writing one yourself. – Costi Ciudatu Aug 06 '16 at 00:05
  • Because the methods in the interface do not allow mutation inherently. You are right though you could implement the interface to have mutatable side effects. – Jeffrey Blattman Aug 12 '16 at 19:04
  • Check style rules are NOT MATURE enough to implicate readability. Readability can't achieved by templating a style, readabability can differs case by case based on the context. See the JDK code, it does not follow any style template, and made by professionals, that shows something. – Daniel Hári Mar 18 '17 at 18:01
  • @DanielHári um, what? Are you really arguing for no style and just letting each dev do what they feel looks best? The JDK absolutely does have a style. Yes, the people that wrote it are not perfect and there are some places where they break their own rules. – Jeffrey Blattman Dec 08 '17 at 20:31
  • Yes, my point is to less stupid automated rule and more subjective style that can't be automated but can be more appropriate. I hate rules. – Daniel Hári Dec 08 '17 at 23:52
46

I like Google's take on it (Google Java Style)

Every constant is a static final field, but not all static final fields are constants. Before choosing constant case, consider whether the field really feels like a constant. For example, if any of that instance's observable state can change, it is almost certainly not a constant. Merely intending to never mutate the object is generally not enough.

Examples:

// 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"};
mateuscb
  • 10,150
  • 3
  • 52
  • 76
  • 7
    I think the first sentence sums this up succintly: "Every constant is a static final field, but not all static final fields are constants." It's easy to use mechanical thinking and just have every static final field in uppercase (and I have been doing this until now) but this is to miss the subtlety of the language. – ayahuasca Dec 17 '15 at 10:59
  • 1
    According to that quote, it boils down to if the field "really feels" like a constant. We're engineers, not psychiatrists. – Jeffrey Blattman Dec 08 '17 at 20:37
  • "Consider...if it really feels like a constant". Someone's feelings really should not enter into the field of engineering. – Jeffrey Blattman Feb 14 '19 at 00:44
  • Then in Guava's code they have it as `private static final Logger logger = Logger.getLogger(Finalizer.class.getName());` – Kenston Choi Jan 06 '20 at 05:03
10

If you are using an automated tool to check your coding standards and it violates said standards then it or the standards should be fixed. If you're using an external standard, fix the code.

The convention in Sun Java is uppercase for public static constants. Obviously a logger is not constant, but represents a mutable thing ( otherwise there would be no point calling methods on it in the hope that something will happen ); there's no specific standard for non-constant final fields.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • 10
    Why are you saying the logger is not constant? It seems constant indeed. The logging is produces is a side-effect of calling its methods, but don't change its observable state. Did I miss something? – KLE Sep 13 '09 at 08:52
  • Check the API. It does have an add/get pair of methods. But you reasoning is flawed anyway. Logging is observable (otherwise, what's the point). – Tom Hawtin - tackline Sep 13 '09 at 10:17
  • 3
    If it were a StringBuilder rather than a logger, then it would perhaps be more obviously non-constant. Even for loggers, methods such as Logger.setLevel() do mutate the receiver observably. Generally uppercase is for those constants which the languages treats as constants and will inline. – Pete Kirkham Sep 13 '09 at 10:18
  • 5
    The logger is not a constant as it is a reference to an object. Constants are values that can't be changed. The object reference is final (so the reference to it can't be changed, e.g. swapped with something else or set to null) but the object itself can. – Spoike Sep 14 '09 at 05:31
  • you are confusing the terms constant and final. in java, final != non-mutable, it means that the object referenced by the field declared final won't change. – Jeffrey Blattman Feb 29 '12 at 01:42
  • @farble1670 I am well aware of the difference. The standard naming (up to 5 at least) was that constants - values capable of being inlined by the compiler - were uppercase. A final reference to a mutable object is not a constant, therefore having it in uppercase *to warn you to recompile dependent classes if you change it* is not appropriate. – Pete Kirkham Feb 29 '12 at 09:28
  • "Obviously a logger is not constant, but represents a mutable thing ( otherwise there would be no point calling methods on it in the hope that something will happen)"- not true. the logger could be immutable and calling some "log" method would not necessarily change the state of the object. – Jeffrey Blattman Jan 25 '13 at 04:07
  • @JeffreyBlattman if it was never the case that the logger represented a mutable thing, you wouldn't bother with having a logger at all - all the calls could be removed from the system without any change in observable behaviour. An object representing a mutable thing is not necessarily itself mutable - a logger might represent logging to the console, which changes the text on the screen, but can be implemented with an immutable object which calls sop. You seem to be arguing that because a final reference might sometimes be to an immutable object, it should be in upper case - is that so? – Pete Kirkham Jan 25 '13 at 09:38
  • @PeteKirkham yes, that's what i'm saying, and it's what Effective Java says as well. but hey, that josh bloch guy probably doesn't know what he's talking about right? in java, immutability means that state of the object is unchanging after construction. e.g., String is immutable, but you can still call methods on it that return new String objects. the point is that none of the methods modify the internal state of the object. please don't try to invent some other definition of immutability, it's confusing. – Jeffrey Blattman Jan 25 '13 at 16:36
  • 1
    @JeffreyBlattman I do not agree that all final references should be upper case, but you are free to adopt whatever coding standards you like. I am sorry that you find the difference between 'mutable object' and 'object which represents a mutable thing' confusing; one example may be your back account number, which itself does not change, but is used to access a variable balance. Look up for the difference between signifier and significand for more details, or an introduction to Leibnitz's monads for how an immutable thing can represent mutability. – Pete Kirkham Jan 25 '13 at 16:46
7

If you google this, you might find that in some cases, the loggers are not defined as static final. Add some quick copy-n-paste to this, and this might explain it.

We use LOGGER in all our code, and this corresponds to our naming convention (and our CheckStyle is happy with it).


We even go further, taking advantage of the strict naming convention in Eclipse. We create a new class with a code template of :

    // private static final Logger LOGGER = Logger.getLogger(${enclosing_type}.class);

The logger is commented out, as initially we don't need it. But should we need it later, we just uncomment it.

Then in the code, we use code templates that expect this logger to be present. Example with the try-catch template:

    try {
      ${cursor} or some other template
    } catch (Exception t) {
      LOGGER.error("${methodName} ${method parameters}", t);
    }

We have a few more templates that use it.

The strict convention allow us to be more productive and coherent with code templates.

Imre
  • 227
  • 3
  • 15
KLE
  • 23,689
  • 4
  • 56
  • 62
  • 5
    Catching Throwable is bad practice, unless you log and rethrow it. Remember Errors: OutOfMemeoryError, etc. Event Exception is not so safe to be catched and handled by yourself in multi-thread applications. – m_vitaly Sep 13 '09 at 09:28
  • 2
    Eclipse syntax is: Logger.getLogger(${enclosing_type}.class); – dogbane Sep 13 '09 at 14:11
  • @fahdshariff Thanks for the precise syntax. I updated my answer. – KLE Sep 13 '09 at 19:50
  • If the "strict conventions" of CheckStyle or PMD helps, then why Guava, and JDK sources does not have ANY applied common style? For example their source have plenty of full inlined blocks where needed. Readability is context dependent, so using strict styling conventions for everything destroys context based decisions, so decreases readability. – Daniel Hári Mar 18 '17 at 21:11
6

I personally think it looks really big in upper-case. Moreover, since it's a class that it's not directly related to the class behaviour, I don't see a major problem in using logger instead of LOGGER. But if you are going to be strictly pedantic, then use LOGGER.

João Silva
  • 89,303
  • 29
  • 152
  • 158
4

Don't forget that PMD will respect a comment with

// NOPMD

in it. This will cause PMD to skip the line from its checks, this will allow you to choose whichever style you want.

Fortyrunner
  • 12,702
  • 4
  • 31
  • 54
3

Usually constants are in uppercase.

Loggers, however, should not be static but looked up for every "new" of the containing class if using the slf4j facade. This avoids some nasty classloader issues in notably web containers, plus it allows the logger framework to do special stuff depending on the invocation context.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
2

If your coding standards - if you have any - say that it should be uppercase then yes.

I don't see any stringent reason for one way or the other. I think it totally depends on your personal likes resp. your company coding standards.

BTW: I prefer "LOGGER" ;-)

Kutzi
  • 1,295
  • 1
  • 15
  • 19
2

I prefer 'logger', i.e. the lower case. The reason is not that it's a constant or not a constant (mutable or immutable). If we'd use that reasoning, we'd have to rename the variable if we change the logging framework (or if the framework changes the mutability of loggers).

For me, other reasons are more important.

  1. A logger is a shadow object in the class and should not be very prominent as it does not implement the main logic. If we use 'LOGGER', it's an eye catcher in the code that attracts too much attention.

  2. Sometimes loggers are declared at instance level (i.e. not as static), and even are injected as a dependency. I wouldn't like to change my code if I decide to change the way I obtain the logger. The code stability wrt. this (hypothetical in many cases) change is the other reason why I prefer the lower case.

fml2
  • 190
  • 11