枚举共享静态查找方法

2022-09-01 12:07:32

我有以下枚举:

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
                + "\'");
    }
}

这工作正常。-方法之所以存在,是因为在与外部合作伙伴通信时,我们只获取要映射到的代码(他们选择的代码)。我需要描述,因为我需要在GUI中显示一个有意义的短语。getValueOf

但是我现在有许多类似的枚举类。它们都有自己的代码和描述,并且需要相同的查找功能。我希望-方法是通用的,所以我不需要为基本相同的方法支持30多个不同的枚举。getValueOf

为了解决这个问题,我想做一个抽象类来定义这个方法并实现一些常见的逻辑,但这是不可能的,因为我无法扩展。Enum

然后我尝试使用以下方法创建一个实用程序类:

public static <T extends Enum<T>> T getValueOf(Enum<T> type, Integer code) {...}

但是带有枚举的泛型令人困惑,我不明白如何让它工作。

基本上,我想知道的是:定义枚举的公共效用的好方法是什么?


答案 1

您需要将实际的枚举类对象作为参数传递给您的方法。然后,您可以使用 获取枚举值。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);

答案 2

这有点棘手,因为该方法是静态的。您实际上需要反射,但是有一种使用标准库功能隐藏此情况的好方法。values()

首先,使用所有枚举类型通用的方法定义一个接口:

public interface Common {
    Integer getCode();
    String getDescription();
}

然后,让所有枚举实现此接口:

public enum MyEnum implements Common {...}

然后,您想要的静态方法如下所示:

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 + "\'" );
}