This question already has an answer here:
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)?
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.
The dialog on this seems to be the antithesis of the conversation on naming
interface
andabstract
classes. I find this alarming, and think that the decision runs much deeper than simply choosing one naming convention and using it always withstatic final
.Abstract and Interface
When naming interfaces and abstract classes, the accepted convention has evolved into not prefixing or suffixing your
abstract class
orinterface
with any identifying information that would indicate it is anything other than a class.The developer is said not to need to know that the above classes are
abstract
or aninterface
.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 howstatic final
may be used in different contexts: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 atprotected
or, its usage is the same:package
visibilityHere, we don't care that
logger
is astatic final
member variable. It could simply be afinal
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.You wouldn't name it
LOGGER
in this scenario, so why should you name it all uppercase if it wasstatic 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 ofpublic
access, restricted topackage
level.Purpose: Enum
Now you might say, why are you using
static final
integers as anenum
? 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:There are variations of the above that achieve the same purpose of allowing explicit conversion of an
enum->int
andint->enum
. In the scope of streaming this information over a network, native Java serialization is simply too verbose. A simpleint
,short
, orbyte
could save tremendous bandwidth. I could delve into a long winded compare and contrast about the pros and cons ofenum
vsstatic final int
involving type safety, readability, maintainability, etc.; fortunately, that lies outside the scope of this discussion.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:Instead, we do the following:
If your
static final
block of integers serves as a looseenum
, 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:
This file contains a list of
MyObject
objects serialized into a byte stream and written to this file. This file has 325 bytes ofMyObject
objects, but without knowing the size of eachMyObject
you have no way of knowing which bytes belong to eachMyObject
. So, you define the size ofMyObject
onMyObject
: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 manyMyObject
objects follow in the file: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 astruct
is simply a class with all public members and no constructor. It's simply a datastruct
ure. So, you can declare aclass
instruct
like fashion: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) thisstruct
s members would look something like:These aren't
static
orfinal
, yet they are publicly exposed members that can be directly set. For this reason, I think that when astatic 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]
private
variable that should be indistinguishable from aprivate
instance variable, then name them the same. all lowercaseenum
style block ofstatic
values, then name it as you would anenum
. pascal case: initial-cap each wordMethodology 2: Private vs Public
[objective; logical]
Methodology 2 basically condenses its context into visibility, and leaves no room for interpretation.
private
orprotected
then it should be all lowercase.public
orpackage
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.(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.)
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.