Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm being forced to use the common anti-pattern of a public interface Constants which many classes in this project implement. Long story short, I need to have a List constant which is pre-populated with values. Normally I would do this like so:

public static final List<String> MY_CONSTANT = new ArrayList<String>();
static {
    MY_CONSTANT.add("foo");
    MY_CONSTANT.add("bar");
    // ...
}

Unfortunately, I can't use static initializers in an interface. So after much frustration, I finally have my implementation as follows:

public static final List<String> MY_CONSTANT = new ArrayList<String>() {
    private static final long serialVersionUID = 1898990046107150596L;
    {
        add("foo");
        add("bar");
        // ...
    }
}

I hate the fact that I've made an anonymous extension like this and it makes me cringe. Are there any better techniques I can use to accomplish this? Changing the Constants file to a class instead of an interface isn't an option. As I said, I'm just retouching a large, pre-existing code base.

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

If you only need constant of java.util.List type you can use static method java.util.Arrays.asList:

import static java.util.Arrays.asList;

...

public static final List<String> MY_CONSTANT = asList("foo", "bar", "baz");

which creates immutable list instance with passed values.

In cases when more complex object needs to be initialised I like to use static methods which create my constant:

public static final SomeComplexObject constant = createMyConstant();

private static SomeComplexObject createMyConstant() {
    SomeComplexObject constant = new SomeComplexObject();
    constant.setProp1(...);
    constant.setProp2(...);
    ...
    return makeItSomehowImmutable(constant);
}

In your case you won't be able to declare private static method inside interface, so the only thing I find reasonable is to create separate utility class with static methods which create constants, declare your method there and reuse it just like with java.util.Arrays.asList method.

Hope this helps...

share|improve this answer
    
Great ideas, both. Thanks! –  Jeff Gohlke Aug 28 '13 at 18:41
add comment

Not sure I understand your specific case entirely, but couldn't you just use enums for that purpose?

As in...

Simple version...

public enum MyConstants {
    FOO, BAR
}
// use method name() to get "FOO" or "BAR"...

Version with actual String values...

public enum MyConstants {
    FOO("foo"), BAR("bar");
    private String value; 
    MyConstants(String value) {
        this.value = value;
    }
    public String getValue() {
        return value;
    }
}
share|improve this answer
    
Certainly this could work, but I want to reduce complexity, not add more. +1 –  Jeff Gohlke Aug 28 '13 at 18:42
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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