33

Is interface an acceptable place to store my

public static final Foo bar

Do you extrapolate them to be read from outside of the program? Do you make up a super class for it?

How do you do it, when situation presents itself?

James Raitsev
  • 92,517
  • 154
  • 335
  • 470
  • I don't understand your question. Are you looking for the Singleton pattern? – PeterT Jun 02 '11 at 21:47
  • 3
    No. I am asking what is the best place to hold constants used throughout the application. Singleton is one way of doing it .. but us it the best? – James Raitsev Jun 02 '11 at 21:57

5 Answers5

53

I'd put each constant into the class or interface it's most closely related to (e.g. because it will be use by its methods).

A very seductive but ultimately very foolish idea is to have one "constants class" (or interface) that contains all constants used in the application. This looks "neat" at first glance, but is not good for maintainability because you want to group things by the functionality they implement, not by technical details like being constants (would you put all interfaces into a dedicated package? All abstract classes?).

The idea is also foolish because any change to that class/interface then (because of constant inlining) requires all classes that use any of the constants to be rebuilt - i.e. pretty much the entire app. So the bigger the app gets, the more frequently you need such a full rebuild, and the longer it takes. I worked on such a project, where this issue led to a 15 minute pause about every other day for every developer...

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 2
    I agree that if constants are used in only one class, you're better off putting it in that class directly. But what about constants used throughout the code? I personally find that having a global constant class is useful for that, even more so using a static import – Rand Jun 02 '11 at 23:56
  • how do you feel about an interface vs an abstract class when it comes to means of storing Constant data? – James Raitsev Jun 03 '11 at 00:13
  • 9
    @Rand: Any constant has some sort of meaning, and it should be part of a class connected to that meaning and named accordingly. Even if a constant is used throughout the code but always in relation to one class, it should clearly be part of that class (e.g. BorderLayout.CENTER). If you can't pin it on one particular class, having a class or interface specifically for it is OK, but it should be specific to a domain concept or subsystem, not a general dumping ground for constants - e.g. SwingConstants. – Michael Borgwardt Jun 03 '11 at 07:41
  • 4
    I just deleted my `public interface Constants` containing all public static final constants. – Sorter Sep 19 '18 at 07:26
  • 1
7

If you are talking about a simple application the Constants class approach is fine:

public class Constants {
    private Constants() {} // no way to instantiate this class
    public static final String MY_VAL = "123";
}

If you're building a larger app you should be using dependency injection, take a look at How can I inject a property value into a Spring Bean which was configured using annotations?

Community
  • 1
  • 1
Abdullah Jibaly
  • 53,220
  • 42
  • 124
  • 197
2

I've used Abdullah Jibaly's approach but using nested classes, which provides a nice way for grouping consts. I've seen this go 3 levels deep and if good names are chosen, it can still work quite well.

One might choose to use final classes for this instead of interface classes to avoid violating Item #19 on Josh Bloch's list (Effective Java 2nd edition).

public final class Const {
    private Const() {} // prevent instantiation

    /** Group1 constants pertain to blah blah blah... */
    public static final class Group1 {
        private Group1() {} // prevent instantiation

        public static final int MY_VAL_1 = 1;
        public static final int MY_VAL_2 = 42;
    }

    /** Group2 constants pertain to blah blah blah... */
    public static final class Group2 {
        private Group2() {} // prevent instantiation

        public static final String MY_ALPHA_VAL = "A";
        public static final String MY_ALPHA_VAL = "B";
    }

}
Will
  • 102
  • 1
  • 6
  • If I take this approach, and anytime I add a constant in Group2, would it require the build of all the classes that use Const? Or just build all the classes use Group2? much thanks – Faraz May 11 '18 at 19:46
  • I guess that would depend on the incremental build solution you have in place. I have used eclipse w/jdk 6 and 8 and and IDE-driven update that is dealing with the change you've described isn't slow in my experience. – Will May 23 '18 at 15:43
2

This is bad practice. Classes are intended to be independent from one another therefore you should avoid global variables at all costs. A more realistic approach is to have a config file, usually in JSON, YAML, or XML file format, and have your program read from this file on start up.

Dennis
  • 3,962
  • 7
  • 26
  • 44
0

I would use an abstract final class since it would be a more explicit declaration of the modifiers as opposed to using an interface. But, like Michael said, they should be logically grouped and be part of an existing class or interface if they semantically belong there.

Lirm
  • 413
  • 1
  • 4
  • 11