Named constants (thus, variables which values are known at compile time, and which don't change during program execution) that are to be accessible across classes can be listed and accessed in a number of different ways. Here are the ones I know, after considerable and time-consuming research:
- Declare constants in an interface, implement the interface, and refer to the constants directly.
- Declare constants in an interface, static import the interface (or individual constants), and refer to the constants directly.
- Declare constants in a class having a private default private constructor, and refer to the constants via their fully qualified names.
- Declare constants in a class having a private default private constructor, static import the class (or individual constants), and refer to the constants directly.
- Declare constants in an enum having an accessor method, and somehow access each constant by passing the same constant to the accessor method in order to obtain the value of the constant that we are passing... Looks circular and doesn't make any sense to me...or are we passing string literals(!) - the very thing we wanted to avoid by using constants in the first place? Not to mention that we now suddenly have made access to each constant more verbose and complicated by having to go via a method.
- Declare constants in a file that doesn't have to be compiled, a.k.a. properties file, and then access each constant by passing a string literal (!) with the name of the constant to a method, which, of course, defeats much of the purpose of what we are trying to accomplish since we are using constants in order not having to deal with error-prone and unsecure string literals...
I don't understand. In order to resolve some issues with listing constants in an interface or a class, alternative and more complicated solutions that seem to defeat the very purpose of what we want (a way to access named constants across classes, in order to avoid [repeated] literals, and in order to set the literals at one location) are suggested by various sources on the Web.
Another example not already mentioned: Is there any compelling point with ResourceBundle (beyond not having to recompile every time a constant is changed)? Why not just have an interface called Language that extends any one of a number of other interfaces such as German, English, Spanish, etc. in which String constants are declared with literals in the local language? Then the language can be switched in a matter of seconds by simply letting Language extend another language than the present one. (If one doesn't want to use interfaces for reasons described as an antipattern, then use classes.)
To me it seems that the pain of having to recompile every time a constant is changed (shouldn't be very often) is an easy burden compared to the complications introduced by ResourceBundle and its related entities.
If anyone can shine some light on these issues, I think it would be a blessing for a lot of people.