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?
3 Answers 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.
-
-
1If 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– Kevin Krumwiede08/28/2015 03:35:49Commented Aug 28, 2015 at 3:35
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– dsollen08/28/2015 13:28:03Commented Aug 28, 2015 at 13:28
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– dsollen08/28/2015 13:26:14Commented Aug 28, 2015 at 13:26
Bundle
keys orIntent
actions or something like that?