30

私は次の列挙型を持っています:

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

これは問題なく動作します。-getValueOfメソッドが存在するのは、外部パートナーと通信するときに、マップするコード(彼らが選択した)のみを取得するためです。GUIで意味のあるフレーズを表示する必要があるため、説明が必要です。

しかし、私は今、いくつかの同様の列挙型クラスを持っています。すべて独自のコードと説明があり、同じルックアップ機能が必要です。-methodを汎用にしたかったgetValueOfので、基本的に同じメソッドで30以上の異なる列挙型をサポートする必要はありません。

これを解決するために、このメソッドを定義し、いくつかの共通論理を実装するための抽象クラスを作成したかったのですが、拡張できないため、これは不可能ですEnum

次に、次のメソッドを使用してUtilityクラスを作成しようとしました。

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

しかし、列挙型を使用したジェネリックは混乱を招き、これを機能させる方法がわかりません。

基本的に私が知りたいのは、列挙型に共通の効用を定義するための良いアプローチは何ですか?

4

2 に答える 2

25

実際の列挙型クラスオブジェクトをパラメータとしてメソッドに渡す必要があります。次に、を使用して列挙値を取得できます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);
于 2012-04-12T10:50:08.283 に答える
8

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 + "\'" );
}
于 2012-04-12T11:01:10.940 に答える