我有以下枚举:
public enum MyEnum{
A(10, "First"), //
B(20, "Second"), //
C(35, "Other options");
private Integer code;
private String description;
private MyEnum(Integer code, String description) {
this.code = code;
this.description = description;
}
public Integer getCode() {
return code;
}
public String getDescription() {
return description;
}
public static MyEnum getValueOf(Integer code) {
for (MyEnum e : MyEnum.values()) {
if (e.getCode().equals(code)) {
return e;
}
}
throw new IllegalArgumentException("No enum const " + MyEnum.class.getName() + " for code \'" + code
+ "\'");
}
}
Run Code Online (Sandbox Code Playgroud)
哪个工作正常.这种getValueOf方法的存在是因为在与外部合作伙伴进行通信时,我们只获得要映射到的代码(他们选择).我需要描述,因为我需要在GUI中显示一个有意义的短语.
但我现在有许多类似的枚举类.所有人都有自己的代码和描述,他们需要相同的查找功能.我希望getValueOf-method是通用的,所以我不需要为基本相同的方法支持30多个不同的枚举.
为了解决这个问题,我想创建一个抽象类来定义这个方法并实现一些常见的逻辑,但这是不可能的,因为我无法扩展Enum.
然后我尝试使用以下方法创建一个Utility类:
public static <T extends Enum<T>> T getValueOf(Enum<T> type, Integer code) {...}
Run Code Online (Sandbox Code Playgroud)
但Enums的泛型令人困惑,我不明白如何使这个工作.
基本上我想知道的是:为枚举定义一个通用实用程序有什么好方法?
Pét*_*rök 23
您需要将实际的枚举类对象作为参数传递给您的方法.然后你可以使用枚举值Class.getEnumConstants().
为了能够访问getCode()实例,您应该在接口中定义它并使所有枚举类型实现该接口:
interface Encodable {
Integer getCode();
}
public static <T extends Enum<T> & Encodable> T getValueOf(Class<T> enumClass, Integer code) {
for (T e : enumClass.getEnumConstants()) {
if (e.getCode().equals(code)) {
return e;
}
}
throw new IllegalArgumentException("No enum const " + enumClass.getName() + " for code \'" + code
+ "\'");
}
...
public enum MyEnum implements Encodable {
...
}
MyEnum e = getValueOf(MyEnum.class, 10);
Run Code Online (Sandbox Code Playgroud)
这有点棘手,因为该values()方法是静态的.您实际上需要反射,但有一种很好的方法可以使用标准库功能隐藏它.
首先,使用所有枚举类型共有的方法定义一个接口:
public interface Common {
Integer getCode();
String getDescription();
}
Run Code Online (Sandbox Code Playgroud)
然后,让所有枚举实现此接口:
public enum MyEnum implements Common {...}
Run Code Online (Sandbox Code Playgroud)
您想要的静态方法如下所示:
public static <T extends Enum<T> & Common> T getValueOf( Class<T> type, Integer code ) {
final EnumSet<T> values = EnumSet.allOf( type );
for(T e : values) {
if(e.getCode().equals( code )) {
return e;
}
}
throw new IllegalArgumentException( "No enum const " + type.getName() + " for code \'" + code + "\'" );
}
Run Code Online (Sandbox Code Playgroud)