如何消除重复的枚举码?

2022-09-01 23:21:40

我有大量的枚举来实现这个接口:

/**
 * 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();
}

一个典型的例子是:

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;
            }
        }
    }
}

可以想象,这些方法在CodableEnum的所有实现中几乎都是相同的。我想消除这种重复,但坦率地说,我不知道该怎么做。我尝试使用如下所示的类:

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);  
}

但事实证明这是相当无用的,因为:

  1. 枚举不能扩展类
  2. 枚举的元素(SKYPE、GOOGLE_TALK等)无法扩展类
  3. 我无法提供 getByCode() 的默认实现,因为 DefaultCodableEnum 本身不是 Enum。我尝试更改DefaultCodableEnum以扩展java.lang.Enum,但这似乎不是允许的。

有什么不依赖于反思的建议吗?谢谢 唐


答案 1

您可以将重复的代码分解为一个类:CodeableEnumHelper

public class CodeableEnumHelper {
    public static CodeableEnum getByCode(String code, CodeableEnum[] values) {
        for (CodeableEnum e : values) {
            if (e.getCode().equalsIgnoreCase(code)) {
                return e;
            }
        }
        return null;
    }
}

每个类仍然必须实现一个方法,但该方法的实际实现至少已经集中在一个地方。CodeableEnumgetByCode

public enum IMType implements CodeableEnum {
    ...
    public IMType getByCode(String code) {
        return (IMType)CodeableEnumHelper.getByCode(code, this.values());
    } 
}

答案 2

抽象枚举可能非常有用(目前不允许)。但是,如果你想游说Sun中的某个人添加它,那么存在一个提案和原型:

http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html

太阳 RFE:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766