<p>I have a large number of Enums that implement this interface:</p>

<pre><code>/**
 * Interface for an enumeration, each element of which can be uniquely identified by its code
 */
public interface CodableEnum {

    /**
     * Get the element with a particular code
     * @param code
     * @return
     */
    public CodableEnum getByCode(String code);

    /**
     * Get the code that identifies an element of the enum
     * @return
     */
    public String getCode();
}
</code></pre>

<p>A typical example is:</p>

<pre><code>public enum IMType implements CodableEnum {

    MSN_MESSENGER("msn_messenger"),
    GOOGLE_TALK("google_talk"),
    SKYPE("skype"),
    YAHOO_MESSENGER("yahoo_messenger");

    private final String code;

    IMType (String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }   

    public IMType getByCode(String code) {
        for (IMType e : IMType.values()) {
            if (e.getCode().equalsIgnoreCase(code)) {
                return e;
            }
        }
    }
}
</code></pre>

<p>As you can imagine these methods are virtually identical in all implementations of CodableEnum. I would like to eliminate this duplication, but frankly don't know how. I tried using a class such as the following:</p>

<pre><code>public abstract class DefaultCodableEnum implements CodableEnum {

    private final String code;

    DefaultCodableEnum(String code) {
        this.code = code;
    }

    public String getCode() {
        return this.code;
    }   

    public abstract CodableEnum getByCode(String code);  
}
</code></pre>

<p>But this turns out to be fairly useless because:</p>

<ol>
<li>An enum cannot extend a class</li>
<li>Elements of an enum (SKYPE, GOOGLE_TALK, etc.) cannot extend a class</li>
<li>I cannot provide a default implementation of getByCode(), because DefaultCodableEnum is not itself an Enum. I tried changing DefaultCodableEnum to extend java.lang.Enum, but this doesn't appear to be allowed.</li>
</ol>

<p>Any suggestions that do not rely on reflection?
Thanks,
Don</p>

[{'answer_id': 77298, 'author': 'Daniel Spiewak', 'author_id': 9815, 'author_profile': 'https://Stackoverflow.com/users/9815', 'pm_score': 1, 'selected': False, 'text': "<p>Unfortunately, I don't think that there is a way to do this.  Your best bet would pro ably be to give up in emums altogether and use conventional class extension and static members.  Otherwise, get used to duplicating that code.  Sorry.</p>\n"}, {'answer_id': 77321, 'author': 'Dave Hillier', 'author_id': 1575281, 'author_profile': 'https://Stackoverflow.com/users/1575281', 'pm_score': 0, 'selected': False, 'text': '<p>It seems like you are actually implementing run time type information. Java provides this as a language feature. </p>\n\n<p>I suggest you look up RTTI or reflection.</p>\n'}, {'answer_id': 77355, 'author': 'Jorn', 'author_id': 8681, 'author_profile': 'https://Stackoverflow.com/users/8681', 'pm_score': 0, 'selected': False, 'text': "<p>I don't think this is possible. However, you could use the enum's valueOf(String name) method if you were going to use the enum value's name as your code.</p>\n"}, {'answer_id': 77393, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<p>How about a static generic method? You could reuse it from within your enum's getByCode() methods or simply use it directly. I always user integer ids for my enums, so my getById() method only has do do this: return values()[id]. It's a lot faster and simpler.</p>\n"}, {'answer_id': 77465, 'author': 'Alex Miller', 'author_id': 7671, 'author_profile': 'https://Stackoverflow.com/users/7671', 'pm_score': 3, 'selected': False, 'text': '<p>Abstract enums are potentially very useful (and currently not allowed).  But a proposal and prototype exists if you\'d like to lobby someone in Sun to add it:</p>\n\n<p><a href="http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html" rel="noreferrer">http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html</a></p>\n\n<p>Sun RFE:</p>\n\n<p><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766" rel="noreferrer">http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766</a></p>\n'}, {'answer_id': 77486, 'author': 'Greg Mattes', 'author_id': 13940, 'author_profile': 'https://Stackoverflow.com/users/13940', 'pm_score': 2, 'selected': False, 'text': '<p>I had a similar issue with a localization component that I wrote. My component is designed to access localized messages with enum constants that index into a resource bundle, not a hard problem.</p>\n\n<p>I found that I was copying and pasting the same "template" enum code all over the place. My solution to avoid the duplication is a code generator that accepts an XML configuration file with the enum constant names and constructor args. The output is the Java source code with the "duplicated" behaviors.</p>\n\n<p>Now, I maintain the configuration files and the generator, not all of the duplicated code. Everywhere I would have had enum source code, there is now an XML config file. My build scripts detect out-of-date generated files and invoke the code generator to create the enum code.</p>\n\n<p><p>You can see this component <a href="http://virtualteamtls.svn.sourceforge.net/viewvc/virtualteamtls/trunk/jill" rel="nofollow noreferrer">here</a>. The template that I was copying and pasting is factored out into <a href="http://virtualteamtls.svn.sourceforge.net/viewvc/virtualteamtls/trunk/jill/resources/com/iparelan/jill/jill.xsl?view=markup" rel="nofollow noreferrer">an XSLT stylesheet</a>. The <a href="http://virtualteamtls.svn.sourceforge.net/viewvc/virtualteamtls/trunk/jill/src/com/iparelan/jill/Jill.java?view=markup" rel="nofollow noreferrer">code generator</a> runs the stylesheet transformation. An <a href="http://virtualteamtls.svn.sourceforge.net/viewvc/virtualteamtls/trunk/jill/src/com/iparelan/jill/jill.xml?view=markup" rel="nofollow noreferrer">input file</a> is quite concise compared to the generated enum source code.</p>\n\n<p>HTH,<br/>\nGreg</p>\n'}, {'answer_id': 77578, 'author': 'Mwanji Ezana', 'author_id': 7288, 'author_profile': 'https://Stackoverflow.com/users/7288', 'pm_score': 0, 'selected': False, 'text': '<p>If you really want inheritance, don\'t forget that you can <a href="http://snipplr.com/view/1655/typesafe-enum-pattern" rel="nofollow noreferrer">implement the enum pattern yourself</a>, like in the bad old Java 1.4 days.</p>\n'}, {'answer_id': 78029, 'author': 'Javamann', 'author_id': 10166, 'author_profile': 'https://Stackoverflow.com/users/10166', 'pm_score': 0, 'selected': False, 'text': "<p>About as close as I got to what you want was to create a template in IntelliJ that would 'implement' the generic code (using enum's valueOf(String name)). Not perfect but works quite well.</p>\n"}, {'answer_id': 78306, 'author': 'dave', 'author_id': 14355, 'author_profile': 'https://Stackoverflow.com/users/14355', 'pm_score': 5, 'selected': True, 'text': '<p>You could factor the duplicated code into a <code>CodeableEnumHelper</code> class:</p>\n\n<pre><code>public class CodeableEnumHelper {\n    public static CodeableEnum getByCode(String code, CodeableEnum[] values) {\n        for (CodeableEnum e : values) {\n            if (e.getCode().equalsIgnoreCase(code)) {\n                return e;\n            }\n        }\n        return null;\n    }\n}\n</code></pre>\n\n<p>Each <code>CodeableEnum</code> class would still have to implement a <code>getByCode</code> method, but the actual implementation of the method has at least been centralized to a single place.</p>\n\n<pre><code>public enum IMType implements CodeableEnum {\n    ...\n    public IMType getByCode(String code) {\n        return (IMType)CodeableEnumHelper.getByCode(code, this.values());\n    } \n}\n</code></pre>\n'}, {'answer_id': 78511, 'author': 'triggerNZ', 'author_id': 13822, 'author_profile': 'https://Stackoverflow.com/users/13822', 'pm_score': 1, 'selected': False, 'text': '<p>Create a type-safe utility class which will load enums by code:</p>\n\n<p>The interface comes down to:</p>\n\n<pre><code>public interface CodeableEnum {\n    String getCode();\n}\n</code></pre>\n\n<p>The utility class is:</p>\n\n<pre><code>import java.lang.reflect.InvocationTargetException;\n\n\npublic class CodeableEnumUtils {\n    @SuppressWarnings("unchecked")\n    public static &lt;T extends CodeableEnum&gt;  T getByCode(String code, Class&lt;T&gt; enumClass) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {\n        T[] allValues = (T[]) enumClass.getMethod("values", new Class[0]).invoke(null, new Object[0]);\n        for (T value : allValues) {\n            if (value.getCode().equals(code)) {\n                return value;\n            }\n        }\n        return null;\n}\n</code></pre>\n\n<p>}</p>\n\n<p>A test case demonstrating usage:</p>\n\n<pre><code>import junit.framework.TestCase;\n\n\npublic class CodeableEnumUtilsTest extends TestCase {\n    public void testWorks() throws Exception {\n    assertEquals(A.ONE, CodeableEnumUtils.getByCode("one", A.class));\n      assertEquals(null, CodeableEnumUtils.getByCode("blah", A.class));\n    }\n\nenum A implements CodeableEnum {\n    ONE("one"), TWO("two"), THREE("three");\n\n    private String code;\n\n    private A(String code) {\n        this.code = code;\n    }\n\n    public String getCode() {\n        return code;\n    }   \n}\n}\n</code></pre>\n\n<p>Now you are only duplicating the getCode() method and the getByCode() method is in one place. It might be nice to wrap all the exceptions in a single RuntimeException too :)</p>\n'}, {'answer_id': 81912, 'author': 'Tom Hawtin - tackline', 'author_id': 4725, 'author_profile': 'https://Stackoverflow.com/users/4725', 'pm_score': 3, 'selected': False, 'text': "<p>To tidy up dave's code:</p>\n\n<pre><code>public class CodeableEnumHelper {\n    public static &lt;E extends CodeableEnum&gt; E getByCode(\n        String code, E[] values\n    ) {\n        for (E e : values) {\n            if (e.getCode().equalsIgnoreCase(code)) {\n                return e;\n            }\n        }\n        return null;\n    }\n}\n\npublic enum IMType implements CodableEnum {\n    ...\n    public IMType getByCode(String code) {\n        return CodeableEnumHelper.getByCode(code, values());\n    } \n}\n</code></pre>\n\n<p>Or more efficiently:</p>\n\n<pre><code>public class CodeableEnumHelper {\n    public static &lt;E extends CodeableEnum&gt; Map&lt;String,E&gt; mapByCode(\n        E[] values\n    ) {\n        Map&lt;String,E&gt; map = new HashMap&lt;String,E&gt;();\n        for (E e : values) {\n            map.put(e.getCode().toLowerCase(Locale.ROOT), value) {\n        }\n        return map;\n    }\n}\n\npublic enum IMType implements CodableEnum {\n    ...\n    private static final Map&lt;String,IMType&gt; byCode =\n        CodeableEnumHelper.mapByCode(values());\n    public IMType getByCode(String code) {\n        return byCode.get(code.toLowerCase(Locale.ROOT));\n    } \n}\n</code></pre>\n"}, {'answer_id': 82005, 'author': 'Nicolas', 'author_id': 1730, 'author_profile': 'https://Stackoverflow.com/users/1730', 'pm_score': 0, 'selected': False, 'text': "<p>In your specific case, the getCode() / getByCode(String code) methods seems very closed (euphemistically speaking) to the behaviour of the toString() / valueOf(String value) methods provided by all enumeration. Why don't you want to use them?</p>\n"}, {'answer_id': 2471851, 'author': 'sleske', 'author_id': 43681, 'author_profile': 'https://Stackoverflow.com/users/43681', 'pm_score': 0, 'selected': False, 'text': '<p>Another solution would be not to put anything into the enum itself, and just provide a bi-directional map Enum &lt;-> Code for each enum. You could e.g. use <a href="http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/ImmutableBiMap.html" rel="nofollow noreferrer">ImmutableBiMap</a> from Google Collections for this.</p>\n\n<p>That way there no duplicate code at all.</p>\n\n<p>Example:</p>\n\n<pre><code>public enum MYENUM{\n  VAL1,VAL2,VAL3;\n}\n\n/** Map MYENUM to its ID */\npublic static final ImmutableBiMap&lt;MYENUM, Integer&gt; MYENUM_TO_ID = \nnew ImmutableBiMap.Builder&lt;MYENUM, Integer&gt;().\nput(MYENUM.VAL1, 1).\nput(MYENUM.VAL2, 2).\nput(MYENUM.VAL3, 3).\nbuild();\n</code></pre>\n'}, {'answer_id': 2867061, 'author': 'Marius Burz', 'author_id': 110750, 'author_profile': 'https://Stackoverflow.com/users/110750', 'pm_score': 0, 'selected': False, 'text': '<p>In my opinion, this would be the easiest way, without reflection and without adding any extra wrapper to your enum.</p>\n\n<p>You create an interface that your enum implements:</p>\n\n<pre><code>public interface EnumWithId {\n\n    public int getId();\n\n}\n</code></pre>\n\n<p>Then in a helper class you just create a method like this one:</p>\n\n<pre><code>public &lt;T extends EnumWithId&gt; T getById(Class&lt;T&gt; enumClass, int id) {\n    T[] values = enumClass.getEnumConstants();\n    if (values != null) {\n        for (T enumConst : values) {\n            if (enumConst.getId() == id) {\n                return enumConst;\n            }\n        }\n    }\n\n    return null;\n}\n</code></pre>\n\n<p>This method could be then used like this:</p>\n\n<pre><code>MyUtil.getInstance().getById(MyEnum.class, myEnumId);\n</code></pre>\n'}, {'answer_id': 5368044, 'author': 'bueyuekt', 'author_id': 668132, 'author_profile': 'https://Stackoverflow.com/users/668132', 'pm_score': 1, 'selected': False, 'text': '<p>Here I have another solution:</p>\n\n<pre><code>interface EnumTypeIF {\nString getValue();\n\nEnumTypeIF fromValue(final String theValue);\n\nEnumTypeIF[] getValues();\n\nclass FromValue {\n  private FromValue() {\n  }\n\n  public static EnumTypeIF valueOf(final String theValue, EnumTypeIF theEnumClass) {\n\n    for (EnumTypeIF c : theEnumClass.getValues()) {\n      if (c.getValue().equals(theValue)) {\n        return c;\n      }\n    }\n    throw new IllegalArgumentException(theValue);\n  }\n}\n</code></pre>\n\n<p>The trick is that the inner class can be used to hold "global methods".</p>\n\n<p>Worked pretty fine for me. OK, you have to implement 3 Methods, but those methods,\nare just delegators.</p>\n'}]
['https://Stackoverflow.com/questions/77213', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2648/']