3

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?

  • 2
    Yes, that feels wrong to me as well. Pick one option or the other (I agree with you, as I usually prefer enums), but maintaining both is just more work and a potential source of errors and bugs in the future. – FrustratedWithFormsDesigner Aug 24 '15 at 17:42
  • 1
    Perhaps you can explain why you want to iterate a group of string values? Creating an enum only to be able to do that doesn't seem the best solution to me. – Kwebble Aug 24 '15 at 20:09
  • Please explain "used just as constant strings." Are they required to be strings by some API they're used with? For example, are they Android Bundle keys or Intent actions or something like that? – Kevin Krumwiede Aug 28 '15 at 4:59
  • @KevinKrumwiede yes? Specifically they are used almost exclusevely for sting comparison with existing strings or for appending to existing strings. They are things like URL endpoint and/or Parameter keys or special values in a Parameter value (for instance AND and OR are used in our filter parameter). Since our URL/params come as strings to be parsed, and the few URL we write will have to be strings or use URLBuilder that wants strings to build up the URL, we effectively only want these as Strings. – dsollen Aug 28 '15 at 13:31
3

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.

  • Make it immutable. – Basilevs Aug 25 '15 at 17:23
  • 1
    If the constants are consistently named (same prefix or something) or you want to collect all the static final strings defined in a class, you could use reflection to populate the collection at runtime. This avoids the possibility of forgetting to add new constants to the collection. – Kevin Krumwiede Aug 28 '15 at 3:35
1

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.

  • I'm not entirely certain this complain applies. My suggestion was setting the constant equal to the param. so Public Static String Filter = MyEnum.Filter.ToString() or something like that. A change to the enum value will update the static, the only inconsistency risk is if an enum param is added and no constant made, but that's easily caught the first time someone wants the constant. I still think it's probably ugly and not desirable, just not certain this complain in particular applies? – dsollen Aug 28 '15 at 13:28
0

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.

  • the constants are mostly being used for string comparisons, withing URL and url parameters for a rest interface. Thus the are used 99% of the time as string for string comparisons. I want to iterate over some simply to iterate over potential parameters of a URL (to exclude all the prams we handle so I can get a list of prams we don't explicitly process to pass through a proxy), but this is the edge case. They are not statically importing entirely. They will call (for example) RestParam.Filter not just Filter. – dsollen Aug 28 '15 at 13:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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