This rule raises an issue when an interface consists only of constant definitions without other members.
Why is this an issue?
An interface that consists solely of constant definitions is a bad practice. The purpose of interfaces is to provide an API, not implementation
details. That is, they should provide functions in the first place and constants only to assist these functions, for example, as possible
arguments.
If an interface contains constants only, move them either to somewhere else, or replace the interface with an Enum or a final class with a
private constructor.
How to fix it
If the concrete value of the constants is not essential, and they serve as mere identifiers, replace the interface with an enum
like
in the following example:
public interface Status { // Noncompliant, enum should be used
int OPEN = 1;
int CLOSED = 2;
}
public enum Status { // Compliant
OPEN,
CLOSED
}
In some cases, enums are not a suitable option because the concrete constant value is important. Then you should check whether it is appropriate to
move them to a specific existing class, for example, if that class is the primary user of the constants:
interface AuxiliaryConstants { // Noncompliant, implementation detail of WordPacker
int BITS_PER_WORD = 16;
int WORD_MASK = (1 << BITS_PER_WORD) - 1;
int HI_WORD_BK_MASK = ~(WORD_MASK << BITS_PER_WORD);
}
class WordPacker {
public static int getHiWord(int value) {
return (value >>> AuxiliaryConstants.BITS_PER_WORD);
}
public static int setHiWord(int value, int wordValue) {
return (value & AuxiliaryConstants.HI_WORD_BK_MASK) |
(wordValue << AuxiliaryConstants.BITS_PER_WORD);
}
}
class WordPacker { // Compliant
private static final int BITS_PER_WORD = 16;
private static final int WORD_MASK = (1 << BITS_PER_WORD) - 1;
private static final int HI_WORD_BK_MASK = ~(WORD_MASK << BITS_PER_WORD);
public static int getHiWord(int value) {
return (value >>> BITS_PER_WORD);
}
public static int setHiWord(int value, int wordValue) {
return (value & HI_WORD_BK_MASK) | (wordValue << BITS_PER_WORD);
}
}
If this is not the case and several classes are using the constants equally, you should use a final class with a private constructor. Unlike
interfaces, they can neither be inherited from nor instantiated.
public interface ColorTheme { // Noncomplient, final class should be used
int COLOR_ERROR = 0xff0000; // red
int COLOR_WARNING = 0xffff00; // yellow
int COLOR_OK = 0x00cf00; // green
}
public final class ColorTheme { // Compliant
public static final int COLOR_ERROR = 0xff0000; // red
public static final int COLOR_WARNING = 0xffff00; // yellow
public static final int COLOR_OK = 0x00cf00; // green
private ColorTheme() {}
}
Resources
Articles & blog posts