I recommend a combination of static imports and interfaces for constants.
If a Java interface has constant field declarations, bear in mind that these are implicitly public, static and final (see the Java Language Specification, Section 9.3.) You can therefore always omit these modifiers, leaving only the type, and your constant interface would look like this:
public interface Constants {
int AGE = 0x23;
String NAME = "Andrew";
boolean IGNORE = true;
}
This should, of course, only ever be used as follows:
import static Constants.*;
public Whatever {
public String method() {
return String.format("%s is %d%c", NAME, AGE, IGNORE ? '?' : '!');
}
}
I have no issues using this style in my production code, and feel it leads to a very neat, compact constants collection, and can cope with various types of constant, which an enum couldn't, as well as being able to be extended if requred, unlike an enum.
Another possibility, which not everyone will approve of, is to nest interfaces (or even enum types) in your parent interface, allowing you to group your constants. This :
interface MoreConstants {
int MAGIC = 0xCAFEBABE;
interface PROPERTIES {
String NAME = "name";
}
enum ERRORS {
ON_FIRE, ASLEEP, BROKEN, UNSURE;
}
}
and access them like this, assuming a static import of the MoreConstants interface:
if (!PROPERTIES.NAME.equals(value)) {
return ERRORS.UNSURE;
}
Of course, these interfaces should never be implemented, which I would consider bad practice. The only way to ensure this, however, is strict code reviews...