115

there is a rule which says:

Names representing constants (final variables) must be all uppercase using underscore to separate words (taken from http://geosoft.no/development/javastyle.html)

that works fine for primitive types like int or strings:

private static final int MAX_COUNT = 10;

But what's about non primitive types? In most cases I've seen the following:

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

or in singletons, where instance variable is not in upper case.

The question is what is the right way to declare those types of variables (like log and instance)?

Aleksey
  • 1,309
  • 2
  • 10
  • 12
  • 2
    The convention applies, irrespective of the type of the variable. Violations of this are either exceptions to this rule to facilitate ease of typing or plain typos. – adarshr Aug 31 '11 at 15:48
  • 3
    I normally name it `LOG` - but my colleagues seem not to like calling sth. like `LOG.info("LOG not log!")` :) – Thomas Aug 31 '11 at 15:48
  • Please cite the source of the rule (adds to the question's quality). – Paul Bellora Aug 31 '11 at 15:49
  • 3
    I normally name it `LOGGER`. It is a constant. – Christoffer Hammarström Aug 31 '11 at 16:06
  • 4
    It's not a rule, it's a canonical convention, and like all consistency it's a refuge for the weak minded. There are many conventions in java that need to be ignored -- and this is one of them. It's basically tipping its hat to hungarian notation, which was always a very bad idea. What happens, for example, when you decide that this isn't a constant (static final) any more? Ok, if we're lucky we've got a refactoring tool like IntelliJ or Eclipse that'll make changes to every use of the symbol, but if we're unlucky we have vim and a change like this becomes very painful.t – Software Engineer Dec 02 '15 at 09:58
  • 18
    Consistency is a refuge for people who must read my the code later, and shouldn't need to learn all of the reasons I thought I was smarter than the community consensus. – gladed Aug 26 '16 at 14:57
  • The marked duplicates question accepted answer differs from this questions accepted anwer. Might be worth consolidating both questions. – tkruse Oct 02 '17 at 04:53
  • 4
    @Engineer Dollery, conventions are for better understanding of others programs and they are not for **"weak minded"** and you shouldn't disrespect people who don't see things from your perspective. https://en.wikipedia.org/wiki/Coding_conventions – Arash Aug 03 '18 at 08:25

9 Answers9

79

That's still a constant. See the JLS for more information regarding the naming convention for constants. But in reality, it's all a matter of preference.


The names of constants in interface types should be, and final variables of class types may conventionally be, a sequence of one or more words, acronyms, or abbreviations, all uppercase, with components separated by underscore "_" characters. Constant names should be descriptive and not unnecessarily abbreviated. Conventionally they may be any appropriate part of speech. Examples of names for constants include MIN_VALUE, MAX_VALUE, MIN_RADIX, and MAX_RADIX of the class Character.

A group of constants that represent alternative values of a set, or, less frequently, masking bits in an integer value, are sometimes usefully specified with a common acronym as a name prefix, as in:

interface ProcessStates {
  int PS_RUNNING = 0;
  int PS_SUSPENDED = 1;
}

Obscuring involving constant names is rare:

  • Constant names normally have no lowercase letters, so they will not normally obscure names of packages or types, nor will they normally shadow fields, whose names typically contain at least one lowercase letter.
  • Constant names cannot obscure method names, because they are distinguished syntactically.
mre
  • 43,520
  • 33
  • 120
  • 170
  • In the JLS it says: `final variables of class types may conventionally be ... all uppercase`. However, I'm with you in keeping things consistent and using upper case for all constants. – Thomas Aug 31 '11 at 15:52
  • Thanks, that makes sense. I just started thinking that I'm missing something because of frequent facing violation of conventions, especially for log variable. – Aleksey Aug 31 '11 at 18:30
  • 9
    "... final variables of class types ***may*** conventionally be ..." – Andy Thomas Sep 01 '11 at 20:10
  • 1
    They are fields themselves, so why should `obscuring a field` be something to consider? I can sort of see the point about obscuring a type name, but you can't exactly have a collision that wouldn't be handled by the IDE/compiler. Say you have `class Error` and a `static final int Error = 0;` Where would the collision exist? You can't assign an `Error` instance to an `int` variable. You can't assign an `int` to an `Error` variable. I don't see how there could ever be a collision in this case. Could you provide an example where a true collision would result from a type sharing the same name? – crush Sep 05 '13 at 15:56
  • 1
    @crush: in your example, the collision would happen in the mind of the reader of the code. In other words, it's confusion for no good reason. I can see lowerCamelcase field names for some static constants. I've done it myself. I understand that the convention is upper case. – Gilbert Le Blanc Sep 05 '13 at 16:35
  • Constant Interface == code smell. Should have used an enum – Software Engineer Dec 02 '15 at 09:59
  • 4
    Does the UPPER_CASE convention apply to a `final` **non**-`static` *local* variable, such as in `void method() { final int VALUE = 5; /* ... */ }`? – code_dredd Sep 14 '16 at 01:49
  • @ray, It's up to the developer, but I usually just camel case those. – mre Sep 14 '16 at 13:46
  • 1
    @mre, Yeah, that's what I ended up doing. Thanks for the suggestion. I just thought posting a full question for that would be overkill. – code_dredd Sep 14 '16 at 13:47
57

The dialog on this seems to be the antithesis of the conversation on naming interface and abstract classes. I find this alarming, and think that the decision runs much deeper than simply choosing one naming convention and using it always with static final.

Abstract and Interface

When naming interfaces and abstract classes, the accepted convention has evolved into not prefixing or suffixing your abstract class or interface with any identifying information that would indicate it is anything other than a class.

public interface Reader {}
public abstract class FileReader implements Reader {}
public class XmlFileReader extends FileReader {}

The developer is said not to need to know that the above classes are abstract or an interface.

Static Final

My personal preference and belief is that we should follow similar logic when referring to static final variables. Instead, we evaluate its usage when determining how to name it. It seems the all uppercase argument is something that has been somewhat blindly adopted from the C and C++ languages. In my estimation, that is not justification to continue the tradition in Java.

Question of Intention

We should ask ourselves what is the function of static final in our own context. Here are three examples of how static final may be used in different contexts:

public class ChatMessage {
    //Used like a private variable
    private static final Logger logger = LoggerFactory.getLogger(XmlFileReader.class);

    //Used like an Enum
    public class Error {
        public static final int Success = 0;
        public static final int TooLong = 1;
        public static final int IllegalCharacters = 2;
    }

    //Used to define some static, constant, publicly visible property
    public static final int MAX_SIZE = Integer.MAX_VALUE;
}

Could you use all uppercase in all three scenarios? Absolutely, but I think it can be argued that it would detract from the purpose of each. So, let's examine each case individually.


Purpose: Private Variable

In the case of the Logger example above, the logger is declared as private, and will only be used within the class, or possibly an inner class. Even if it were declared at protected or package visibility, its usage is the same:

public void send(final String message) {
    logger.info("Sending the following message: '" + message + "'.");
    //Send the message
}

Here, we don't care that logger is a static final member variable. It could simply be a final instance variable. We don't know. We don't need to know. All we need to know is that we are logging the message to the logger that the class instance has provided.

public class ChatMessage {
    private final Logger logger = LoggerFactory.getLogger(getClass());
}

You wouldn't name it LOGGER in this scenario, so why should you name it all uppercase if it was static final? Its context, or intention, is the same in both circumstances.

Note: I reversed my position on package visibility because it is more like a form of public access, restricted to package level.


Purpose: Enum

Now you might say, why are you using static final integers as an enum? That is a discussion that is still evolving and I'd even say semi-controversial, so I'll try not to derail this discussion for long by venturing into it. However, it would be suggested that you could implement the following accepted enum pattern:

public enum Error {
    Success(0),
    TooLong(1),
    IllegalCharacters(2);

    private final int value;

    private Error(final int value) {
        this.value = value;
    }

    public int value() {
        return value;
    }

    public static Error fromValue(final int value) {
        switch (value) {
        case 0:
            return Error.Success;
        case 1:
            return Error.TooLong;
        case 2:
            return Error.IllegalCharacters;
        default:
            throw new IllegalArgumentException("Unknown Error value.");
        }
    }
}

There are variations of the above that achieve the same purpose of allowing explicit conversion of an enum->int and int->enum. In the scope of streaming this information over a network, native Java serialization is simply too verbose. A simple int, short, or byte could save tremendous bandwidth. I could delve into a long winded compare and contrast about the pros and cons of enum vs static final int involving type safety, readability, maintainability, etc.; fortunately, that lies outside the scope of this discussion.

The bottom line is this, sometimes static final int will be used as an enum style structure.

If you can bring yourself to accept that the above statement is true, we can follow that up with a discussion of style. When declaring an enum, the accepted style says that we don't do the following:

public enum Error {
    SUCCESS(0),
    TOOLONG(1),
    ILLEGALCHARACTERS(2);
}

Instead, we do the following:

public enum Error {
    Success(0),
    TooLong(1),
    IllegalCharacters(2);
}

If your static final block of integers serves as a loose enum, then why should you use a different naming convention for it? Its context, or intention, is the same in both circumstances.


Purpose: Static, Constant, Public Property

This usage case is perhaps the most cloudy and debatable of all. The static constant size usage example is where this is most often encountered. Java removes the need for sizeof(), but there are times when it is important to know how many bytes a data structure will occupy.

For example, consider you are writing or reading a list of data structures to a binary file, and the format of that binary file requires that the total size of the data chunk be inserted before the actual data. This is common so that a reader knows when the data stops in the scenario that there is more, unrelated, data that follows. Consider the following made up file format:

File Format: MyFormat (MYFM) for example purposes only
[int filetype: MYFM]
[int version: 0] //0 - Version of MyFormat file format
[int dataSize: 325] //The data section occupies the next 325 bytes
[int checksumSize: 400] //The checksum section occupies 400 bytes after the data section (16 bytes each)
[byte[] data]
[byte[] checksum]

This file contains a list of MyObject objects serialized into a byte stream and written to this file. This file has 325 bytes of MyObject objects, but without knowing the size of each MyObject you have no way of knowing which bytes belong to each MyObject. So, you define the size of MyObject on MyObject:

public class MyObject {
    private final long id; //It has a 64bit identifier (+8 bytes)
    private final int value; //It has a 32bit integer value (+4 bytes)
    private final boolean special; //Is it special? (+1 byte)

    public static final int SIZE = 13; //8 + 4 + 1 = 13 bytes
}

The MyObject data structure will occupy 13 bytes when written to the file as defined above. Knowing this, when reading our binary file, we can figure out dynamically how many MyObject objects follow in the file:

int dataSize = buffer.getInt();
int totalObjects = dataSize / MyObject.SIZE;

This seems to be the typical usage case and argument for all uppercase static final constants, and I agree that in this context, all uppercase makes sense. Here's why:

Java doesn't have a struct class like the C language, but a struct is simply a class with all public members and no constructor. It's simply a data structure. So, you can declare a class in struct like fashion:

public class MyFile {
    public static final int MYFM = 0x4D59464D; //'MYFM' another use of all uppercase!

    //The struct
    public static class MyFileHeader {
        public int fileType = MYFM;
        public int version = 0;
        public int dataSize = 0;
        public int checksumSize = 0;
    }
}

Let me preface this example by stating I personally wouldn't parse in this manner. I'd suggest an immutable class instead that handles the parsing internally by accepting a ByteBuffer or all 4 variables as constructor arguments. That said, accessing (setting in this case) this structs members would look something like:

MyFileHeader header = new MyFileHeader();
header.fileType     = buffer.getInt();
header.version      = buffer.getInt();
header.dataSize     = buffer.getInt();
header.checksumSize = buffer.getInt();

These aren't static or final, yet they are publicly exposed members that can be directly set. For this reason, I think that when a static final member is exposed publicly, it makes sense to uppercase it entirely. This is the one time when it is important to distinguish it from public, non-static variables.

Note: Even in this case, if a developer attempted to set a final variable, they would be met with either an IDE or compiler error.


Summary

In conclusion, the convention you choose for static final variables is going to be your preference, but I strongly believe that the context of use should heavily weigh on your design decision. My personal recommendation would be to follow one of the two methodologies:

Methodology 1: Evaluate Context and Intention [highly subjective; logical]

  • If it's a private variable that should be indistinguishable from a private instance variable, then name them the same. all lowercase
  • If it's intention is to serve as a type of loose enum style block of static values, then name it as you would an enum. pascal case: initial-cap each word
  • If it's intention is to define some publicly accessible, constant, and static property, then let it stand out by making it all uppercase

Methodology 2: Private vs Public [objective; logical]

Methodology 2 basically condenses its context into visibility, and leaves no room for interpretation.

  • If it's private or protected then it should be all lowercase.
  • If it's public or package then it should be all uppercase.

Conclusion

This is how I view the naming convention of static final variables. I don't think it is something that can or should be boxed into a single catch all. I believe that you should evaluate its intent before deciding how to name it.

However, the main objective should be to try and stay consistent throughout your project/package's scope. In the end, that is all you have control over.

(I do expect to be met with resistance, but also hope to gather some support from the community on this approach. Whatever your stance, please keep it civil when rebuking, critiquing, or acclaiming this style choice.)

Community
  • 1
  • 1
crush
  • 16,713
  • 9
  • 59
  • 100
  • Well here is a +1 from me. I just found that line `public transient static final List AVAILABLE_PARAMETERS;` and imho this should be named as `availableParamters`. I think only primitive types should be upper case .. – Stefan Falk Nov 21 '14 at 08:21
  • 3
    Downvoting cause not capitalized everywhere. – Nikola Yovchev Jun 20 '16 at 08:53
  • 2
    @baba So downvoted because not following blind conventions that are rendered obsolete by modern development environments? Good logic. – crush Jun 21 '16 at 14:59
  • 2
    @crush, constants are always capitalized, regardless of their type and their visibility, regardless if they are primitive or not. That's how it is and how it should be as it is specified by the language specification. IDE's have nothing to do with it. Loggers are not constants, as they have functionality, hence they shouldn't be capiralized. See, easy, and, most of all, compliant with the standard. – Nikola Yovchev Aug 05 '16 at 10:16
  • 1
    @NikolaYovchev Why do you need to know by naming convention that a variable is a constant? Just because the standard says so isn't a good reason not to evolve. Obviously I know what the standard says, and have chosen to offer a deviate because we have evolved beyond the days when we needed names to offer inspection into the traits of a variable. – crush Jan 18 '17 at 18:18
  • @Nikola, "Loggers are not constants, as they have functionality" - But so do strings. You can do all kinds of operations yet they are declared with uppercase. What's the difference between a String and a Logger? – LegendLength Oct 13 '17 at 02:12
  • 1
    @LegendLength a constant is something that is private/public static final in the Java language, kinda like an enum. Same reason a constant String is capitalized is the reason the enum values are capitalized, cause you can't change them at runtime. Try to do lowercase on a static final String and assign it to itself and see what happens. You could also see the widely accepted approach is for loggers to be not capitalized: https://www.slf4j.org/manual.html, https://projectlombok.org/api/lombok/extern/slf4j/Slf4j.html are lowercase! – Nikola Yovchev Oct 13 '17 at 14:04
  • 2
    Try to modify a static final logger at runtime and see how that gets you. You ignored my question. – LegendLength Oct 15 '17 at 01:31
  • You can't reassign anything to a final field (without reflection) outside of a constructor. That is why you can't assign to a `final String` member at runtime, regardless of it if is static or not. It has nothing to do with its constantness. Strings are a special case in Java, but that doesn't sufficiently explain why they should be all caps. Neither does "because Oracle said so." – crush Oct 17 '17 at 22:41
  • Actually "Nikola Yovchev" mentioned a good point. Content is important not appearance. Loggers are not constants like, **"final ArrayList list = new ArrayList<>();"** although its a final. But if they were, like **"final int MAX_COUNT = 10;"**, should follow conventions. Conventions are for better understanding of others programs. https://en.wikipedia.org/wiki/Coding_conventions – Arash Aug 03 '18 at 09:06
  • For method 2 why is `protected` considered lowercase while `package` is considered uppercase? `protected` is also `package` but `protected` may be visible in an api through inheritance. I would make variables that are public or protected uppercase and everything else lowercase. For an api nobody should be making classes in my package to view variables but they may extend classes. Visibility in an api should either be inherited or public and if it is visible from the api it should be uppercase. – John Mercier Oct 29 '18 at 12:54
  • @JohnMercier "`protected` is also `package`" No it's not. Package is essentially public, but restricted to access in the same package...protected is not accessible by classes in the same package. Package is initialcap because it is a restricted form of public. Any fields that can be accessed from outside the hierarchy of your class should be initial capped. Fields that can only be accessed from within the hierarchy of your class should be camel-case. I wouldn't consider protected fields to be part of an API. Typically, you should hide field access behind setters/getters when developing an API. – crush Oct 29 '18 at 16:38
  • I'm still not sure I agree about protected. https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – John Mercier Oct 29 '18 at 18:22
  • "The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package." – John Mercier Oct 29 '18 at 18:23
  • 1
    @JohnMercier After actually testing this, I see that you are right.. I wouldn't expect `protected` to work that way, and I can't imagine why the Java developers would make `protected` accessible by non-subclasses within the same package. I mean, that's the entire point of having a `package` level accessibility modifier isn't it? It doesn't work this way in most other languages with a concept of `protected` access. I'll have to give this more thought, but maybe you are right and it should be initial capped since it is publicly accessible (don't have to subclass to access). My mind is blown. – crush Oct 29 '18 at 23:27
  • Im not sure how to compare it with other languages. C++ has friends but no package scope. In java I would only consider using package-private for an internal api. Users of an api should not create classes in your packages. Protected is good when you need a contract/api with subclasses that is not public. Like a protected method which adds to a private list in the super class which has a public immutable getter. For constants it makes sense to use uppercase on protected final variables of a class since it may be used outside the package or module. – John Mercier Oct 30 '18 at 03:56
  • This answer is based on a failure to understand the first pages of any java book, which the author goes on to defend instead of having the character to simply admit such a basic mistake, wasting everyone's time in the process. – mouselabs Jun 27 '23 at 19:16
15

The language doesn't care. What's important is to follow the established styles and conventions of the project you're working on, such that other maintainers (or you five months from now) have the best possible chance of not being confused.

I think an all-uppercase name for a mutable object would certainly confuse me, even if the reference to that object happened to be stored in a static final variable.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
hmakholm left over Monica
  • 23,074
  • 3
  • 51
  • 73
11

A constant reference to an object is not a constant, it's just a constant reference to an object.

private static final is not what defines something to be a constant or not. It's just the Java way to define a constant, but it doesn't mean that every private static final declaration was put there to define a constant.

When I write private static final Logger I'm not trying to define a constant, I'm just trying to define a reference to an object that is private (that it is not accessible from other classes), static (that it is a class level variable, no instance needed) and final (that can only be assigned once). If it happens to coincide with the way Java expects you to declare a constant, well, bad luck, but it doesn't make it a constant. I don't care what the compiler, sonar, or any Java guru says. A constant value, like MILLISECONDS_IN_A_SECOND = 1000 is one thing, and a constant reference to an object is another.

Gold is known to shine, but not everything that shines is gold.

drakorg
  • 404
  • 4
  • 14
  • Is `final` without the `static` also a constant? If not, what's it called? – Kartik Chugh Oct 04 '16 at 16:57
  • I think you are saying I can call it a constant if I'd like -- but what I'm really getting at is if I should capitalize final variables – Kartik Chugh Oct 05 '16 at 19:34
  • 7
    The old concept of a constant has been lost. Constants used to point to actual fixed values. Nowadays you have a constant reference to an object that can change its state. If that is a constant for you, call it a constant (and capitalize it). If not, then don't. It basically goes down to the kind of treatment you will give to that object and what you expect from it. Considering every private static final reference a constant for its sole signature is wrong. So I wouldn't call every final variable a constant either. Now if that final variable is a constant in your mind, then do it. – drakorg Oct 07 '16 at 22:59
8

Well that's a very interesting question. I would divide the two constants in your question according to their type. int MAX_COUNT is a constant of primitive type while Logger log is a non-primitive type.

When we are making use of a constant of a primitive types, we are mutating the constant only once in our code public static final in MAX_COUNT = 10 and we are just accessing the value of the constant elsewhere for(int i = 0; i<MAX_COUNT; i++). This is the reason we are comfortable with using this convention.

While in the case of non-primitive types, although, we initialize the constant in only one place private static final Logger log = Logger.getLogger(MyClass.class);, we are expected to mutate or call a method on this constant elsewhere log.debug("Problem"). We guys don't like to put a dot operator after the capital characters. After all we have to put a function name after the dot operator which is surely going to be a camel-case name. That's why LOG.debug("Problem") would look awkward.

Same is the case with String types. We are usually not mutating or calling a method on a String constant in our code and that's why we use the capital naming convention for a String type object.

Kashif Nazar
  • 20,775
  • 5
  • 29
  • 46
4

There is no "right" way -- there are only conventions. You've stated the most common convention, and the one that I follow in my own code: all static finals should be in all caps. I imagine other teams follow other conventions.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • I mark simple final static types like strings and numbers in all caps for historical reasons. I came from C/C++ where constants are marked in all caps by convention. – Michael Shopsin Aug 31 '11 at 15:51
3

In my opinion a variable being "constant" is often an implementation detail and doesn't necessarily justify different naming conventions. It may help readability, but it may as well hurt it in some cases.

Cellux
  • 71
  • 2
1

These variables are constants, i.e. private static final whether they're named in all caps or not. The all-caps convention simply makes it more obvious that these variables are meant to be constants, but it isn't required. I've seen

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

in lowercase before, and I'm fine with it because I know to only use the logger to log messages, but it does violate the convention. You could argue that naming it log is a sub-convention, I suppose. But in general, naming constants in uppercase isn't the One Right Way, but it is The Best Way.

andronikus
  • 4,125
  • 2
  • 29
  • 46
  • "The Best Way" is still subjective - that is the one issue I have with your answer on this subject. For example, I don't believe it is the best way at all. My personal preference is that `static final` variables should be indistinguishable from other variables. Just like you wouldn't prefix an interface with `IReader` or suffx it with `ReaderInterface`. Instead, you name it `Reader` because the implementation details don't matter to a developer. In the case of the logger, should the developer really know or care if `logger` is static final, or not static final, based on name alone? I think not – crush Sep 05 '13 at 13:08
  • It's true that naming a constant in all caps is kind of an instance of Hungarian notation (e.g. `iMyVar` for an int, `sMyVar` for a string, etc). So I can see not using caps to save typing. However, I'd say that there is value in the coder knowing that a particular variable is `static final`, because they'll get an error if they try to modify it. I believe that saves time in the long run. – andronikus Sep 05 '13 at 16:21
  • The compiler and IDE should/will inform them that they are trying to set the value of a final variable. I do believe it is helpful, though, in the case of publicly accessibly variables. See my argument below for more. – crush Sep 05 '13 at 16:24
  • A constant value is not the same thing as a constant reference to an object. Not even the object referenced by the constant reference is constant. It can still change according to the exposed methods. So, there is nothing constant about your so-called constants. A real constant, on the other hand, would be MILLISECONDS_IN_A_SECOND = 1000, for example. – drakorg Nov 29 '14 at 04:43
0

Don't live fanatically with the conventions that SUN have med up, do whats feel right to you and your team.

For example this is how eclipse do it, breaking the convention. Try adding implements Serializable and eclipse will ask to generate this line for you.

Update: There were special cases that was excluded didn't know that. I however withholds to do what you and your team seems fit.