2 min read

Constants in Java Interfaces

How to properly define and use constants in interfaces
Constants in Java Interfaces

Constants

Constants in interfaces can only be public. No other access modifier can be used. Constants in interfaces are implicitly marked with public static final, so providing these keywords is redundant and unnecessary. An example of a constant in an interface is the following:

public interface Example {

    // Constant
    String GREETING = "Hello";
}

Constants in interfaces are accessed the same way a constant on a class would be accessed.

System.out.println(Example.GREETING);

A class that implements an interface will have access to the constants inside the class as if they were part of the class.

public class MyClass implements Example {

    public void sayHello() {
        System.out.println(GREETING);
    }
}

The Constant Interface Anti-Pattern

This anti-pattern is when you have an interface that doesn't have methods and only has constants. This is referring to an interface whose goal isn't to introduce a type but to provide a home for constants. For example:

public interface App {
    String URL = "https://www.bytesize.press";
    String NAME = "Byte-size";
}

This interface is then used one of two ways. The first is the following:

System.out.println(App.URL);

The second way is much worse. The interface is actually implemented on a class only for the constant variables.

public class Example implements App {

    public void method() {
        System.out.println(URL);
    }
}

The constant interface anti-pattern can introduce constant hiding. This is where you have an interface with a constant and a class that implements that interface with the same constant name that is in the interface. Depending on how this constant is accessed, it can "hide" the value and can have unexpected results. For Example:

public interface MyInterface {
    int CONSTANT = 10;
}

public class MyClass implements MyInterface {
    public static final int CONSTANT = 20;
}

public static void main(final String[] args) {
    System.out.println(MyInterface.CONSTANT);
    System.out.println(MyClass.CONSTANT);
}

This will produce the following:

10
20

Conclusion

Constants should be placed where they make the most sense. If that is an interface, be aware of constant hiding. If you are in a situation where you need a home for constants outlined in the constant interface anti-pattern, using a final class with a private constructor would be the appropriate approach.