How do you define a class of constants in Java?

131,622

Solution 1

Use a final class, and define a private constructor to hide the public one.
For simplicity you may then use a static import to reuse your values in another class

public final class MyValues {

  private MyValues() {
    // No need to instantiate the class, we can hide its constructor
  }

  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

in another class :

import static MyValues.*
//...

if (VALUE1.equals(variable)) {
  //...
}

Solution 2

Your clarification states: "I'm not going to use enums, I am not enumerating anything, just collecting some constants which are not related to each other in any way."

If the constants aren't related to each other at all, why do you want to collect them together? Put each constant in the class which it's most closely related to.

Solution 3

My suggestions (in decreasing order of preference):

1) Don't do it. Create the constants in the actual class where they are most relevant. Having a 'bag of constants' class/interface isn't really following OO best practices.

I, and everyone else, ignore #1 from time to time. If you're going to do that then:

2) final class with private constructor This will at least prevent anyone from abusing your 'bag of constants' by extending/implementing it to get easy access to the constants. (I know you said you wouldn't do this -- but that doesn't mean someone coming along after you won't)

3) interface This will work, but not my preference giving the possible abuse mention in #2.

In general, just because these are constants doesn't mean you shouldn't still apply normal oo principles to them. If no one but one class cares about a constant - it should be private and in that class. If only tests care about a constant - it should be in a test class, not production code. If a constant is defined in multiple places (not just accidentally the same) - refactor to eliminate duplication. And so on - treat them like you would a method.

Solution 4

As Joshua Bloch notes in Effective Java:

  • Interfaces should only be used to define types,
  • abstract classes don't prevent instanciability (they can be subclassed, and even suggest that they are designed to be subclassed).

You can use an Enum if all your constants are related (like planet names), put the constant values in classes they are related to (if you have access to them), or use a non instanciable utility class (define a private default constructor).

class SomeConstants
{
    // Prevents instanciation of myself and my subclasses
    private SomeConstants() {}

    public final static String TOTO = "toto";
    public final static Integer TEN = 10;
    //...
}

Then, as already stated, you can use static imports to use your constants.

Solution 5

My preferred method is not to do that at all. The age of constants pretty much died when Java 5 introduced typesafe enums. And even before then Josh Bloch published a (slightly more wordy) version of that, which worked on Java 1.4 (and earlier).

Unless you need interoperability with some legacy code there's really no reason to use named String/integer constants anymore.

Share:
131,622

Related videos on Youtube

Yuval Adam
Author by

Yuval Adam

λf.(λx.f(x x)) (λx.f(x x))

Updated on July 08, 2022

Comments

  • Yuval Adam
    Yuval Adam almost 2 years

    Suppose you need to define a class which all it does is hold constants.

    public static final String SOME_CONST = "SOME_VALUE";
    

    What is the preferred way of doing this?

    1. Interface
    2. Abstract Class
    3. Final Class

    Which one should I use and why?


    Clarifications to some answers:

    Enums - I'm not going to use enums, I am not enumerating anything, just collecting some constants which are not related to each other in any way.

    Interface - I'm not going to set any class as one that implements the interface. Just want to use the interface to call constants like so: ISomeInterface.SOME_CONST.

    • Dan Dyer
      Dan Dyer over 15 years
      There's some similar discussion here: stackoverflow.com/questions/320588/… . I would use a final class with a private constructor so that it cannot be instantiated.
    • Lordn__n
      Lordn__n over 15 years
      Sorry but "I'm not going to use enums" turns this question into "what's the best way to do something stupid?"
    • Megacan
      Megacan over 15 years
      I'm not saying you are going to implement the interface. But there is no point of using an interface to do that. So, go with the final class : )
    • Leo
      Leo over 15 years
      What's the problem with Enum? You can allways use it to collect 'some constants which are not related to each other in any way'. Hmm?
    • Dan Dyer
      Dan Dyer over 15 years
      Conceptually, an enum is a bad choice if the constants are not related. An enum represents alternative values of the same type. These constants aren't alternatives and they may not even be the same type (some may be strings, some integers, etc.)
    • Leo
      Leo over 15 years
      I don't think that enum is a bad choice for public static final String SOME_CONST = "SOME_VALUE" replacement. Even if constants are not related. I do not see problems here.
  • Yuval Adam
    Yuval Adam over 15 years
    This is not a good idea. This creates dependencies between classes which should have none.
  • Yuval Adam
    Yuval Adam over 15 years
    Jon - they are related in the sense they all belong to the same functionality. However, they are not an enumeration of anything... They do not hold the property that an object is "one of those things".
  • Jon Skeet
    Jon Skeet over 15 years
    Okay. In that case just put them in the class which is closest to the functionality they're related to.
  • Jon Skeet
    Jon Skeet over 15 years
    Where's the benefit of creating a separate class here? While I normally don't hold the Calendar API up as a good example of design, it's fine in terms of "calendar-related constants are in the Calendar class".
  • user54579
    user54579 over 15 years
    the benefit is about not duplicating code, in case you need to reuse constants in more than one class. I guess you can easily see the advantage of this.
  • Jon Skeet
    Jon Skeet over 15 years
    Why would you duplicate code? Just refer to the other class. I find it relatively rare that a constant really stands alone.
  • Ran Biron
    Ran Biron over 15 years
    For better readability I'd also have a private default constructor with no body (and a matching comment).
  • Simon Groenewolt
    Simon Groenewolt over 15 years
    Why not? I'd say that classes that use the same constants have a dependency anyway... And somehow there must be one class that is the most dependent on these constants.
  • liltitus27
    liltitus27 over 10 years
    but bad programmers are going to write code that sucks no matter what you do. That's only so true. If you can take steps to mitigate bad programming, or eliminate it altogether, then you have a bit of a responsibility to do that; be as explicit as possible. A bad programmer can't extend a final class.
  • Brett
    Brett over 10 years
    @liltitus27 To some extent I agree. But do you really want uglified code just to stop one way of poor programmers writing bad code? The code they produce will still be hopeless, but now your code is less readable.
  • Brett
    Brett over 10 years
    If there was only one class using the constants, this could make sense.
  • L. Holanda
    L. Holanda about 8 years
    99% of the time. But not always.
  • L. Holanda
    L. Holanda about 8 years
    "private constructor is the existence of method could never be tested": not true. If you (or your boss) is really paranoid about code coverage reports to be 100%, you can still test this by using reflection and ensuring constructor throws an exception. But, IMHO, this is just formality and doesn't really need to be tested. If you (or team) only really cares what is really important, 100% line coverage is not necessary.
  • Aakash
    Aakash about 7 years
    Pretty old answer, and this comment is probably out of place, but I would use VALUE1.equals(variable) as it avoids NPE.
  • amdev
    amdev almost 6 years
    Good answer, an exemple would be better.
  • amdev
    amdev almost 6 years
    The problem of the 1 is that sometimes you will inject in your code some dependencies to another tier class just to fetch the constant.
  • Kodebetter
    Kodebetter about 5 years
    All fields in an interface are implicitly public, static and final
  • Wit
    Wit about 4 years
    @Kodebetter But interfaces can be extended/implemented to add more fields.