我有大量实现此接口的枚举:
/** * Interface for an enumeration, each element of which can be uniquely identified by it's 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); }
但事实证明这是无用的,因为:
枚举不能扩展类
枚举元素(SKYPE,GOOGLE_TALK等)不能扩展类
我无法提供getByCode()的默认实现,因为DefaultCodableEnum本身不是Enum.我尝试更改DefaultCodableEnum以扩展java.lang.Enum,但似乎不允许这样做.
任何不依赖反思的建议?谢谢,唐
您可以将重复的代码分解为一个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; } }
每个CodeableEnum
类仍然必须实现一个getByCode
方法,但该方法的实际实现至少已集中到一个地方.
public enum IMType implements CodeableEnum { ... public IMType getByCode(String code) { return (IMType)CodeableEnumHelper.getByCode(code, this.values()); } }
抽象枚举可能非常有用(目前不允许).但是,如果您想在Sun中为某个人添加游戏来添加它,则存在一个提案和原型:
http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html
Sun RFE:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766
整理戴夫的代码:
public class CodeableEnumHelper { public staticE getByCode( String code, E[] values ) { for (E e : values) { if (e.getCode().equalsIgnoreCase(code)) { return e; } } return null; } } public enum IMType implements CodableEnum { ... public IMType getByCode(String code) { return CodeableEnumHelper.getByCode(code, values()); } }
或者更有效率:
public class CodeableEnumHelper { public staticMap mapByCode( E[] values ) { Map map = new HashMap (); for (E e : values) { map.put(e.getCode().toLowerCase(Locale.ROOT), value) { } return map; } } public enum IMType implements CodableEnum { ... private static final Map byCode = CodeableEnumHelper.mapByCode(values()); public IMType getByCode(String code) { return byCode.get(code.toLowerCase(Locale.ROOT)); } }