Home » Java » What is the best way to implement constants in Java?

What is the best way to implement constants in Java?

Posted by: admin November 2, 2017 Leave a comment

Questions:

I’ve seen examples like this:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

and supposed that I could have a Constants class to wrap constants in, declaring them static final. I know practically no Java at all and am wondering if this is the best way to create constants.

Answers:

That is perfectly acceptable, probably even the standard.

(public/private) static final TYPE NAME = VALUE;

where TYPE is the type, NAME is the name in all caps with underscores for spaces, and VALUE is the constant value;

I highly recommend NOT putting your constants in their own classes or interfaces.

As a side note: Variables that are declared final and are mutable can still be changed; however, the variable can never point at a different object.

For example:

public static final Point ORIGIN = new Point(0,0);

public static void main(String[] args){

    ORIGIN.x = 3;

}

That is legal and ORIGIN would then be a point at (3, 0).

Questions:
Answers:

I would highly advise against having a single constants class. It may seem a good idea at the time, but when developers refuse to document constants and the class grows to encompass upwards of 500 constants which are all not related to each other at all (being related to entirely different aspects of the application), this generally turns into the constants file being completely unreadable. Instead:

  • If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+.
  • If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren’t only valid to a particular class…which means that the external classes using this constant may be too tightly coupled to the class containing the constant)
  • If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.
Questions:
Answers:

It is a BAD PRACTICE to use interfaces just to hold constants (named constant interface pattern by Josh Bloch). Here’s what Josh advises:

If the constants are strongly tied to
an existing class or interface, you
should add them to the class or
interface. For example, all of the
boxed numerical primitive classes,
such as Integer and Double, export
MIN_VALUE and MAX_VALUE constants. If
the constants are best viewed as
members of an enumerated type, you
should export them with an enum
type. Otherwise, you should export the
constants with a noninstantiable
utility class.

Example:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

About the naming convention:

By convention, such fields have names
consisting of capital letters, with
words separated by underscores. It is
critical that these fields contain
either primitive values or references
to immutable objects.

Questions:
Answers:

In Effective Java (2nd edition), it’s recommended that you use enums instead of static ints for constants.

There’s a good writeup on enums in Java here:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Note that at the end of that article the question posed is:

So when should you use enums?

With an answer of:

Any time you need a fixed set of constants

Questions:
Answers:

Just avoid using an interface:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

It is tempting, but violates encapsulation and blurs the distinction of class definitions.

Questions:
Answers:

I use following approach:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Than, for example, I use Constants.DB.Connection.URL to get constant.
It looks more “object oriently” as for me.

Questions:
Answers:

Creating static final constants in a separate class can get you into trouble. The Java compiler will actually optimize this and place the actual value of the constant into any class that references it.

If you later change the ‘Constants’ class and you don’t do a hard re-compile on other classes that reference that class, you will wind up with a combination of old and new values being used.

Instead of thinking of these as constants, think of them as configuration parameters and create a class to manage them. Have the values be non-final, and even consider using getters. In the future, as you determine that some of these parameters actually should be configurable by the user or administrator, it will be much easier to do.

Questions:
Answers:

The number one mistake you can make is creating a globally accessible class called with a generic name, like Constants. This simply gets littered with garbage and you lose all ability to figure out what portion of your system uses these constants.

Instead, constants should go into the class which “owns” them. Do you have a constant called TIMEOUT? It should probably go into your Communications() or Connection() class. MAX_BAD_LOGINS_PER_HOUR? Goes into User(). And so on and so forth.

The other possible use is Java .properties files when “constants” can be defined at run-time, but not easily user changeable. You can package these up in your .jars and reference them with the Class resourceLoader.

Questions:
Answers:

That’s the right way to go.

Generally constants are not kept in separate “Constants” classes because they’re not discoverable. If the constant is relevant to the current class, keeping them there helps the next developer.

Questions:
Answers:

What about an enumeration?

Questions:
Answers:

I prefer to use getters rather than constants. Those getters might return constant values, e.g. public int getMaxConnections() {return 10;}, but anything that needs the constant will go through a getter.

One benefit is that if your program outgrows the constant–you find that it needs to be configurable–you can just change how the getter returns the constant.

The other benefit is that in order to modify the constant you don’t have to recompile everything that uses it. When you reference a static final field, the value of that constant is compiled into any bytecode that references it.

Questions:
Answers:

I agree that using an interface is not the way to go. Avoiding this pattern even has its own item (#18) in Bloch’s Effective Java.

An argument Bloch makes against the constant interface pattern is that use of constants is an implementation detail, but implementing an interface to use them exposes that implementation detail in your exported API.

The public|private static final TYPE NAME = VALUE; pattern is a good way of declaring a constant. Personally, I think it’s better to avoid making a separate class to house all of your constants, but I’ve never seen a reason not to do this, other than personal preference and style.

If your constants can be well-modeled as an enumeration, consider the enum structure available in 1.5 or later.

If you’re using a version earlier than 1.5, you can still pull off typesafe enumerations by using normal Java classes. (See this site for more on that).

Questions:
Answers:

Based on the comments above I think this is a good approach to change the old-fashioned global constant class (having public static final variables) to its enum-like equivalent in a way like this:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

So then I can refer them to like:

Constants.StringConstant.DB_HOST

Questions:
Answers:

A good object oriented design should not need many publicly available constants. Most constants should be encapsulated in the class that needs them to do its job.

Questions:
Answers:

There is a certain amount of opinion to answer this. To start with, constants in java are generally declared to be public, static and final. Below are the reasons:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

I would never use an interface for a CONSTANTS accessor/object simply because interfaces are generally expected to be implemented. Wouldn’t this look funny:

String myConstant = IMyInterface.CONSTANTX;

Instead I would choose between a few different ways, based on some small trade-offs, and so it depends on what you need:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe

Questions:
Answers:

A Constant, of any type, can be declared by creating an immutable property that within a class (that is a member variable with the final modifier). Typically the static and public modifiers are also provided.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

There are numerous applications where a constant’s value indicates a selection from an n-tuple (e.g. enumeration) of choices. In our example, we can choose to define an Enumerated Type that will restrict the possible assigned values (i.e. improved type-safety):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}

Questions:
Answers:

A single, generic constants class is a bad idea. Constants should be grouped together with the class they’re most logically related to.

Rather than using variables of any kind (especially enums), I would suggest that you use methods. Create a method with the same name as the variable and have it return the value you assigned to the variable. Now delete the variable and replace all references to it with calls to the method you just created. If you feel that the constant is generic enough that you shouldn’t have to create an instance of the class just to use it, then make the constant method a class method.

Questions:
Answers:

FWIW, a timeout in seconds value should probably be a configuration setting (read in from a properties file or through injection as in Spring) and not a constant.

Questions:
Answers:

What is the difference

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2.

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

and using
MyGlobalConstants.TIMEOUT_IN_SECS wherever we need this constant. I think both are same.

Questions:
Answers:

What is the best way to implement constants in Java?

One approach that we should really avoid : using interfaces to define constants.

Creating a interface specifically to declare constants is really the worst thing : it defeats the reason why interfaces were designed : defining method(s) contract.

Even if an interface already exists to address a specific need, declaring the constants in them make really not sense as constants should not make part of the API and the contract provided to client classes.


To simplify, we have broadly 4 valid approaches.

With static final String/Integer field :

  • 1) using a class that declare constants inside but not only.
  • 1 variant) creating a class dedicated to only declare constants.

With Java 5 enum :

  • 2) declaring the enum in a related purpose class (nested class).
  • 2 variant) creating the enum alone (not in a outer class).

TLDR : Which is the best way and where locate the constants ?

In most of cases, the enum way is probably finer than the static final String/Integer way and personally I think that the static final String/Integer way should be used only if we have good reasons to not use enums.
And about where we should declare the constant values, the idea is to search if there exists a class that own a strong semantic and use relationship with constant values. If we find it, we should use it as the constants holder. Otherwise, the constant should be associated to no one particular class.


static final String/ static final Integer versus enum

Enums usage is really a way to strongly considered.
Enums have a great advantage over String or Integer constant field.
They set a stronger compilation constraint.
If you define a method that takes the enum as parameter, you can only pass a enum value defined in the enum class(or null).
With String and Integer you can substitute them with any values of compatible type and the compilation will be fine even if the value is not a defined constant in the static final String/ static final Integer fields.

For example, below two constants defined in a class as static final String fields :

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Here a method that expects to have one of these constants as parameter :

public void process(String constantExpected){
    ...    
}

You can invoke it in this way :

process(MyClass.ONE_CONSTANT);

or

process(MyClass.ANOTHER_CONSTANT);

But no compilation constraint prevents you from invoking it in this way :

process("a not defined constant value");

You would have the error only at runtime and only if you do at a time a check on the transmitted value.

With enum, checks are not required as the client could only pass a enum value in a enum parameter.

For example, here two values defined in a enum class (so constant out of the box):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Here a method that expects to have one of these enum values as parameter :

public void process(MyEnum myEnum){
    ...    
}

You can invoke it in this way :

process(MyEnum.ONE_CONSTANT);

or

process(MyEnum.ANOTHER_CONSTANT);

But the compilation will never allow you from invoking it in this way :

process("a not defined constant value");

Where should we declare the constants ?

If your application contains an existing class that has a specific and strong functional cohesion with the constant values, the 1) and the 2) appear more intuitive.
Generally, it eases the use of the constants if these are declared in the main class that manipulates them or that has a name very natural to guess that we will find it inside.

For example in the JDK library, the exponential and pi constant values are declared in a class that declare not only constant declarations (java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

The clients using mathematics functions rely often on the Math class.
So, they may find constants easily enough and can also remember where E and PI are defined in a very natural way.

If your application doesn’t contain an existing class that has a very specific and strong functional cohesion with the constant values, the 1 variant) and the 2 variant) ways appear more intuitive.
Generally, it doesn’t ease the use of the constants if these are declared in one class that manipulates them while we have also 3 or 4 other classes that manipulate them as much as and no one of these classes seems be more natural than others to host constant values.
Here, defining a custom class to hold only constant values makes sense.
For example in the JDK library, the java.util.concurrent.TimeUnit enum is not declared in a specific class as there is not really one and only one JDK specific class that appear as the most intuitive to hold it :

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Many classes declared in java.util.concurrent use them :
BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , … and really no one of them seems more appropriate to hold the enum.

Questions:
Answers:

I wouldn’t call the class the same (aside from casing) as the constant … I would have at a minimum one class of “Settings”, or “Values”, or “Constants”, where all the constants would live. If I have a large number of them, I’d group them up in logical constant classes (UserSettings, AppSettings, etc.)

Questions:
Answers:

To take it a step further, you can place globally used constants in an interface so they can be used system wide. E.g.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

But don’t then implement it. Just refer to them directly in code via the fully qualified classname.

Questions:
Answers:

For Constants, Enum is a better choice IMHO. Here is an example

public class myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}

Questions:
Answers:

One of the way I do it is by creating a ‘Global’ class with the constant values and do a static import in the classes that need access to the constant.

Questions:
Answers:

static final is my preference, I’d only use an enum if the item was indeed enumerable.

Questions:
Answers:

I use static final to declare constants and go with the ALL_CAPS naming notation. I have seen quite a few real life instances where all constants are bunched together into an interface. A few posts have rightly called that a bad practice, primarily because that’s not what an interface is for. An interface should enforce a contract and should not be a place to put unrelated constants in. Putting it together into a class that cannot be instantiated (through a private constructor) too is fine if the constant semantics don’t belong to a specific class(es). I always put a constant in the class that it’s most related to, because that makes sense and is also easily maintainable.

Enums are a good choice to represent a range of values, but if you are storing standalone constants with an emphasis on the absolute value (eg. TIMEOUT = 100 ms) you can just go for the static final approach.

Questions:
Answers:

I agree with what most are saying, it is best to use enums when dealing with a collection of constants. However, if you are programming in Android there is a better solution: IntDef Annotation.

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

IntDef annotation is superior to enums in one simple way, it takes significantly less space as it is simply a compile-time marker. It is not a class, nor does it have the automatic string-conversion property.