In every application, there are a number of constants that are widely used. And it makes sense to group them in the same class.
Should we use java constants class or interface? We will see two ways to Define Constants In Java:
- Placing constants in an interface
- Placing constants in a Class
Placing constants in an interface
Unfortunately, many applications choose the solution of Placing constants in an interface.
package javabestpractices.constants; interface ConstantsInterface { public static final String COMMUNICATION_EMAIL = "EMAIL"; public static final String COMMUNICATION_PHONE = "PHONE"; public static final String COMMUNICATION_ADDRESS = "ADDRESS"; }
The supposed benefit of this solution is to allow the class to implement such an interface, to refer to those constants without a qualifying class name.
package javabestpractices.constants; public class ContactCustomers implements ConstantsInterface { public void contactCustomer(String contactType) { if(COMMUNICATION_EMAIL.equals(contactType)) { // send email }else if(COMMUNICATION_PHONE.equals(contactType)) { // send phone message }else if(COMMUNICATION_ADDRESS.equals(contactType)) { // send letter } } }
In fact, is a bad utilization of interfaces. An interface should be used to state the services provided by a class, not constants or data.
In addition, constants are used in the implementation part, so it is not a good idea to put them in the interface and expose them with the class’s API.
Placing constants in a Class
A better way to manage constants is to Create a class whose job is to declare these widely-used constants.
package javabestpractices.constants; public final class ConstantsClass { public static final String COMMUNICATION_EMAIL = "EMAIL"; public static final String COMMUNICATION_PHONE = "PHONE"; public static final String COMMUNICATION_ADDRESS = "ADDRESS"; }
The caller class will have access to these constants by importing the constants class “statically” . then refers to these constants using static references.
Static imports allow the static items of one class to be referenced in another without qualification.
package javabestpractices.constants; import static javabestpractices.constants.ConstantsClass.*; public class ContactCustomer { public void contactCustomer(String contactType) { if(COMMUNICATION_EMAIL.equals(contactType)) { // send email }else if(COMMUNICATION_PHONE.equals(contactType)) { // send phone message }else if(COMMUNICATION_ADDRESS.equals(contactType)) { // send letter } } }
Prevent the constants class to be instantiated
Since the only role of this class is to define the constants, there is no need to create an object.
To achieve this we need to declare a private constructor, to prevent the caller to create an instance of this class.
package javabestpractices.constants; public final class ConstantsClass { public static final String COMMUNICATION_EMAIL = "EMAIL"; public static final String COMMUNICATION_PHONE = "PHONE"; public static final String COMMUNICATION_ADDRESS = "ADDRESS"; private ConstantsClass() { throw new AssertionError(); } }
Even better, we can also prevent the native class from calling its own constructor by rising an Exception explicitly.