What is the use of interface constants?
Putting static members into an interface (and implementing that interface) is a bad practice and there is even a name for it, the Constant Interface Antipattern, see Effective Java, Item 17:
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
There are several constant interfaces in the java platform libraries, such as
java.io.ObjectStreamConstants
. These interfaces should be regarded as anomalies and should not be emulated.
To avoid some pitfalls of the constant interface (because you can't prevent people from implementing it), a proper class with a private constructor should be preferred (example borrowed from Wikipedia):
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
And to access the constants without having to fully qualify them (i.e. without having to prefix them with the class name), use a static import (since Java 5):
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
I came across this old question several times now and the accepted answer still confuse me. After a lot of thinking, I think this question can be further clarified.
Why use Interface Constant?
Just compare them:
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
vs
public interface Constants {
double PI = 3.14159;
double PLANCK_CONSTANT = 6.62606896e-34;
}
Same usage. Much less code.
Bad practice?
I think @Pascal Thivent 's answer has the wrong emphasis, here is my version of it:
Putting static members into an interface (and implementing that interface) is a bad practice.
The quote from Effective Java has the assumption of the constant interface being implemented by others, which I think should not (and will not) happen.
When you create an constant interface named something like Constants
, it should not be implemented by anyone. (though technically possible, which is the only issue here)
It won't happen in the standard library
The standard library cannot afford any possible misuse of the design, so you just won't see any there.
However, for daily projects of normal developers, using constants interface is a lot easier because you do not need to worry about static
, final
, empty constructor
, etc, and it will NOT cause any bad design issue. The only downside I can think of is that it still has the name of "interface", but nothing more than that.
Never-ending debate
At the end, I think everyone is just quoting from books, and giving opinions and justifications to their stands. No exception for me. Maybe the decision is still up to the developers of each project. Just go ahead to use it if you feel comfortable. The best we can do is to make it consistent throughout the project.
"The constant interface pattern is a poor use of interfaces"
Whoever concocted this hypothesis, however a guru he/she may be, concocted it on the basis of the need to continue implementing bad habits and practices efficiently. The hypothesis is based on the promotion of the validity of bad software design habits.
I wrote a response rebuttal against that hypothesis here: What is the best way to implement constants in Java? explaining the baseless-ness of this hypothesis.
For 10 years that question had stayed open, until it was closed within 2 hours after I posted my reasons dejustifying this hypothesis, thus exposing UNWILLINGness for debate by those who hold on to this misguided hypothesis dearly.
These are the points I expressed against the hypothesis
The basis for holding this hypothesis is the need for methods and RESTRICTIVE rules to cope with the effects of bad software habits and methodologies.
The proponents of the sentiment "The constant interface pattern is a poor use of interfaces" are unable to provide any reasons other than those caused by the need to cope with the effects of those bad habits and practices.
Solve the fundamental issue.
And then why not make full use and exploit every language feature of the Java language structure to your own convenience. No Jackets Required. Why invent rules to barricade your ineffective lifestyle to discriminate and incriminate more effective lifestyles?
The fundamental issue
is information organisation. Information mediating the process, nd the behaviour of that information should first be understood, along with the so-called business rules - before engineering or supplementing solutions to the process. Such method of information organization was called data normalization a few decades ago.
Then only the engineering of a solution be possible because aligning the granularity and modularity of the components of a solution with the granularity and modularity of the components of the information is the optimal strategy.
There are two or three significant obstacles toward organizing information.
The lack of perception for the need of data-model "normalization".
EF Codd's statements on data normalization are flawed, defective and ambiguous.
The latest fad masquerading as agile engineering is the misguided notion that one should not plan and condition the organization of modules ahead because you can refactor as you go. Refactoring and continuous change without being impeded by future discoveries is used as the excuse. Essential discoveries of behaviour of process information is then, by using accounting tricks to delay profits and assetization, wherefore essential knowledge and their treatment is deemed not needed now.
Using Interface Constants is Good Practice.
Don't make up rules or issue any fatwa against it just because you love your ad-hoc hit-and-run programming habits.
Do not ban gun ownership with the reason that there are people who either do not know how to handle guns or are prone to abuse guns.
If the rules you concoct are meant for programming novices unable to code professionally and that you count yourself amongst them then say so - do not declare your fatwa as applicable to properly normalized data-models.
A silly reasoning - Interfaces were not intended by the founders of the Java language to be used that way?
I don't care what the original intentions of the founding fathers had for the US Constitution. I don't care about the unwritten uncodified intentions. I only care about what is literarily codified in the written Constitution and how I can exploit them for the effective functioning of society.
I only care about what the Java language/platform specs allow me and I intend to exploit them to the full to afford me a medium to express my software solutions efficiently and effectively. No jackets required.
Use of Enum Constants is actually Horrible Practice.
It requires writing extra code to map parameter to value. The fact that the founders of Java did not provide for parameter-value mapping without your writing that mapping code demonstrates Enum Constants are just as unintended use of Java language.
Especially since you are not encouraged to normalize and componentize your parameters, there would be a false impression that parameters mixed into an Enum bag belong to the same dimension.
Constants are API Contract
Don't forget that. If you designed and normalized your data-model, and they include constants,then those constants are contracts. If you did not normalize your data-model, then you should conform to fatwas given on how to practice restrictive coding to cope with that bad habit.
Therefore, Interfaces are a perfect way of implementing Constants' contract.
A strange presumption - What if the interface inadvertently gets implemented.
Yup. Anyone could inadvertently implement any interface inadvertently. Nothing will stand in the way of such inadvertent programmers.
Design and normalize your data-model against leakage
Do not place restrictive decrees to protect presumed bad practices that cause leaking of uncontracted/stray parameters into API. Solve the fundamental issue, rather than place the blame on Interface Constants.
Not using an IDE is bad practice
A normal functioning and EFFECTIVE programmer is not there to prove how long she can stay underwater, how far she could walk in blistering heat or wet thunderstorms. She is to use an efficient tool like a car or bus or at least a bike to take her 10 miles to work everyday.
Do not place restrictions on fellow programmers just because you have an esoteric asceticism obsession with IDE-less programming.
A couple frameworks are designed to help programmers continue practicing bad habits efficiently.
OSGI is such a framework. And so is the decree against Interface Constants too.
Therefore the conclusive answer ...
Interface constants are an effective and efficient way to place into Contract well-designed and normalized components of a data-model.
Interface constants in an appropriately named private interface nested in a class file are also good practice to group all your private constants rather than scatter them all over the file.