Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I am writing a set of junit test classes in Java. There are several constants, for example strings that I will need in different test classes. I am thinking about an interface that defines them and every test class would implement it.

The benefits I see there are:

  • easy access to constants: MY_CONSTANT instead of ThatClass.MY_CONSTANT
  • each constant defined only once

Is this approach rather a good or bad practice? I feel like abusing the concept of interfaces a little bit.

You can answer generally about interfaces/constants, but also about unit tests if there is something special about it.

share|improve this question

6 Answers 6

Joshua Bloch advises against this in his book Effective Java:

That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the classes 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.

You can get the same effect with a normal class that defines the constants, and then use import static com.example.Constants.*;

share|improve this answer
Clap clap clap! Very good citation! – facundofarias Jun 8 at 14:17

In our case we're doing this because the values of the constants represent a contract for end states that a service implementation is required to provide. Putting these constants in the interface specifies the end states as a part of the contract, and if any implementation of the interface didn't use them it would not be doing its job.

SOMETIMES constants are implementation details. SOMETIMES they are not. As usual, an engineer needs to use his brain to decide what to do, and not rely on a sweeping pattern or practice.

share|improve this answer

I don't think it's a good thing to have interfaces only for constants.

But if an interface that defines behavior (methods implementing classes should implement), has constants, it's OK. If it *leaks some implementor's detail" into the API, it's becasuse that's the way it should be. They are also leaking than the implementor implements foo and bar methods.

Take for example the java.awt.Transpatency interface. It has OPAQUE, BITMASK and TRANSLUCENT constants but also has getTransparency() method.

If the designer put those constants there it's becasuse he/she thought that would be stable enough to be part of the interface, as getTransparency() is.

share|improve this answer

Think it is a viewpoint mostly popular in places where design by contract is prevailent.
Interfaces are contracts. Placing constants in interfaces means every class that abides by the contract agrees to the value/concept identified by the constant.

share|improve this answer
interfaces are public contracts. Constant VALUES are private concerns, the public interface should at most expose their names. That's best left to an abstract class. – jwenting Feb 24 '11 at 8:00
Cases in point: javax.naming.Context, javax.ims.Session, and hundreds of such interfaces... – CMR Feb 24 '11 at 12:02
@jwenting Also, could a public interface "at most expose their names", without exposing the values? – CMR Feb 24 '11 at 13:17
that'd depend on the programming language I guess. In case of Java, no. – jwenting Aug 1 '14 at 15:05

A company I worked at made heavy use of interface-imported1 constants. I don't feel any harm came of it.

The question you should be asking yourself is, how important is namespacing to you? In the case of constants, that's really all a class acts as. If you have thousands of constants, you may not want all of those constants always available.

The cool thing about interfaces is it gives you the benefit of working either way - bring in all the namespaces you need, or none of them (and access them explicitly, with MyInterface.CONSTANT). Pretty much the same thing as import static MyInterface.*, but a little bit more obvious.

1: If you're not familiar with Java, I don't mean the import keyword, I just mean brought in via implements MyConstantsInterface

share|improve this answer

I come from a background that is mostly influenced primarily by the 'Ada way' and the '.Net way.' I would say no, that it is probably not best to declare constants within interfaces. It is technically not allowed in c#.

The reason I say no is that a an interface is a form of contract that defines behavior, not state or structure. A constant implies some kind of state (primitive), or an aspect of state (composite or aggregate).

I can appreciate the urge to make defaults and predefined values available to everyone who implements the interface, but perhaps the default state would be better described in an abstract or value object or template , where the defaults would have at least minimal context.

For a more technical guide:

share|improve this answer
Adding more links referring to Static Import (1.5): 1. Wikipedia 2. Oracle Docs referencing @Justinc – Abhijeet B Nov 12 at 3:10
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Reference from Oracle Docs – Abhijeet B Nov 12 at 3:16

protected by gnat May 18 at 10:33

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.