I don't agree with either of the two proposals.
Constants should be in their pertinent classes, not in an all-constant class in either of the two forms proposed.
There shouldn't be constants-only classes/interfaces.
A class CreditCard
(not an internal class) should exist. This class/interface has methods relative to credits cards as well as the constants UI_EXPIRY_MONTH
and UI_ACCOUNT_ID
.
There should exist a class/interface BankAccount
(not an internal class). This class/interface has methods relative to bank accounts as well as constant UI_ACCOUNT_ID
.
For example in the Java API every class/interface has its constants. They are not in a Constants class/interface with hundreds of constants, either grouped into inner classes or not.
For example, these constants pertinent to result sets are in the interface ResultSet
:
static int CLOSE_CURSORS_AT_COMMIT
static int CONCUR_READ_ONLY
static int CONCUR_UPDATABLE
static int FETCH_FORWARD
static int FETCH_REVERSE
static int FETCH_UNKNOWN
static int HOLD_CURSORS_OVER_COMMIT
static int TYPE_FORWARD_ONLY
static int TYPE_SCROLL_INSENSITIVE
static int TYPE_SCROLL_SENSITIVE
This interface has method signatures relative to result sets, and implementing classes implement that behavior. They are not mere constant-holders.
These constants pertinent to UI actions are in the interface javax.swing.Action
:
static String ACCELERATOR_KEY
static String ACTION_COMMAND_KEY
static String DEFAULT
static String LONG_DESCRIPTION
static String MNEMONIC_KEY
static String NAME
static String SHORT_DESCRIPTION
static String SMALL_ICON
Implementing classes have behavior relative to UI actions, they are not mere constant holders.
I know at least one "constants" interface (SwingConstants
) with no methods but it doesn't have hundreds of constants, just a few, and they are all related to directions and positions of UI elements:
static int BOTTOM
static int CENTER
static int EAST
static int HORIZONTAL
static int LEADING
static int LEFT
static int NEXT
static int NORTH
static int NORTH_EAST
static int NORTH_WEST
static int PREVIOUS
static int RIGHT
static int SOUTH
static int SOUTH_EAST
static int SOUTH_WEST
static int TOP
static int TRAILING
static int VERTICAL
static int WEST
I think constants only classes are not good OO design.
Articles in Variable Names
They add little to no value in most cases, but make the code longer to read.
Usually, I'd rarely have a the need for the distinction between a "a" or "the" in the flow of a function, so it doesn't make sense to use articles.
It's a formal programming language and I am fine with it not reading exactly like a natural language. In fact, it's probably better this way, not everything's necessarily so great about natural languages.
There are a few cases where readability can benefit from using articles though, for instance if you want to implement a checker for a "is a" relationship with a method signature like boolean isA(Object o, Class<?> cl)
(I'm not advocating this to be a good idea).
Hard-Coded Strings
It depends on whether you plan to reuse them or not, and whether that reuse is driven by semantics (and not just the fact that the String has the same content in different places) and spread across multiples classes or sub-systems.
To that extent, I usually use these rules:
If you have the same string multiple times and it has the same meaning acros multiple classes, then extract to constants in an interface.
If you have the same string multiple times within a single class and it has the same meaning within that class, then extract to constants within the class.
If you have only a few number of repetitions of as tring, or they just happen to be identical but aren't guaranteed to always be in the future, then I'd leave them inlined.
If any of the above would render maintenance difficult, screw rules 1 to 3 and do whatever works best for you.
Of course, make sure that the constant's name makes the code as semantically valid as the string it holds. That also applies for other things that aren't strings (like Predicates, for instance).
Best Answer
Sun (and now Oracle) maintained a document titled Code Conventions for the Java Programming Language. The last update to this was in '99, but the essence of the style guide line lives on.
Chapter 9 covers naming conventions.
For an identifier type of 'constants':
The examples given:
In a more recent document - its slipped in there. From Variables (The Java Tutorials > Learning the Java Language > Language Basics:
Many static analyzers for Java seek to enforce this. For example checkstyle enforces:
This really boils down to the conventions of the community writing the code... and ideally keeping it the same.
The examples above are given as
static final
ones which are likely derived from the C conventions for#define
- which like C, are replaced in the code during compilation rather than at runtime.The question that then should be asked is "is this behaving like a constant? or is it behaving like a write once field?" - and then following the conventions accordingly. The litmus test for such a question would be "If you were to serialize the object, would you include the final field?" If the answer is that it is a constant then treat it as such (and don't serialize it). On the other hand, if it is part of the state of the object that would need to be serialized, then it isn't a constant.
Whatever the case, it is important to stick with the code style however right or wrong it is. Worse problems erupt from inconsistent conventions within a project than merely something that offends the eye. Consider getting some static analysis tools and configure them to maintain consistency.