Question

Currently my team has a number of constants defined as static final strings. I want to be able to iterate over these strings as if they were an enum in one location, but everywhere else they are used just as constant strings. The other developers do not want them as Enums because they don't want to have to add a .value to the enum every time they want to use the constants, feeling it's too verbose and thus cumbersome.

It seems like the easiest way to maintain the way others have done things while still getting the convenience of iterating (without getting into reflection) is to do both. Have an enum, but in addition define a static final field which is set equal to the enum's value for each enum, so that others can choose to use the static string most of the time, but have the enum to fall back on when they want a true "Enum".

However, somehow this feels wrong to me, even though it meets the two desired needs. Is there a better way of making these strings iterable?

Was it helpful?

Solution

I want to be able to iterate over these strings as if they were an enum in one location, but everywhere else they are used just as constant strings.

So define a list (or vector or array), load the necessary items into it and iterate over that.
If you really only need it in one location, define and load it there. If there's a chance that you might want to use it again then define it alongside the static String values.

OTHER TIPS

Yes.

Whether or not you need to use enums is a different story, but:

If you use both enums and String constants you will need a way to keep these values in synch in your code. The enums you are iterating over need to match the constants used by your peers. Maintaining this code is going to be difficult. Someone at some point is going to come along and change an enum and then not update your constant String values accordingly--or vice versa.

This is a good place where you can take advantage of methods in Enum objects, I have used this many times in the past. By explicitly providing the constant in the enum itself and using a method to return the constant from the enum, you are going to tie the enum's value and it's String representation together in the same place, making code maintenance much easier.

I think duplicating these values in your code is inevitably going to end up in diverging representations of what you really want.

The other developers do not want them as Enums because they don't want to have to add a .value to the enum every time they want to use the constants, feeling it's too verbose and thus cumbersome.

This is easy. The other developers' objections aren't simply differences of opinion; they're factually wrong. You can statically import the enum constants to avoid constantly typing the enum class name. I would argue that this reduces clarity, but that's a matter of opinion. For example, if you have an enum called MetasyntacticVariable, you could write:

import static MetasyntacticVariable.*;

class Derp {
   void someMethod(MetasyntacticVariable var) {
      if(var == FOO) { ... }
   }
}

Change the enum to a non-instantiable class containing string constants, and the code size is about the same, but you give up type safety:

import static MetasyntacticVariables.*;

class Derp {
   void someMethod(String var) {
      if(FOO.equals(var)) { ... }
   }
}

I hope you're not using the constant interface antipattern to avoid importing constants.

Licensed under: CC-BY-SA with attribution
scroll top