列挙型で繰り返しコードを削減する方法を継承機能に?

CARVEN:

私が働いているJavaアプリケーションでは、私は、静的なってしまった列挙型の数持ってfromString、実際の列挙値に文字列を変換するためにそれらのメソッドを。

だから、私はすべての私の列挙型は、そのコードのすべての時間を繰り返す必要がなくて拡張することができ、そこから「基本」クラスを持っていると考えていました。列挙型は、クラスを拡張することができないので、私が行うことを計画してきた私が代わりにインタフェースを介してそれを行うことができるかもしれないということです。

私がきたことは次のとおりであります:

public interface IBaseEnum {

    String enumVal = null;

    public static <T extends Enum<T> & IBaseEnum> Enum<T> fromString(String strVal) {
        if (strVal == null) return null;
        // T.values() has error because T is not recognised to have the method values()
        for (T myEnum : T.values()) {
            if (myEnum.enumVal.equals(strVal.toUpperCase())) {
                return myEnum;
            }
        }
        return null;
    }
}

そして、その静的メソッドを継承するために、私が実施していきますIBaseEnum私の実際の列挙型に:

public enum Colour implements IBaseEnum {
   Red("red");
   //...
}

しかし、私は内の型の問題を抱えていますIBaseEnumラインは、T.values()ジェネリック型があるためエラーを有しているTバック列挙自体に参照することができず、方法がその訴えているようにvalues()見られません。

これは、列挙型で継承機能に正しい方法ですか?それ以外の場合は、どのように私は、私はすべての単一の列挙型のメソッドの同じセットをコピー/貼り付け、繰り返す必要はありませんので、列挙型のメソッドを継承することができますか?

ernest_k:

あなたのコードは、その私が言及する必要があり、動作しないいくつかの理由があります:

  • String enumVal = null;IBaseEnumインターフェースという、numVal暗黙の取得publicstaticおよびfinal修飾子を。ただし、予定のenumValインスタンスプロパティであることを。
  • T.values():もちろん、これはコンパイルされません。しかし、(またはあなたがクラスのインスタンスを持っていた)、あなたはまだ、このダイナミックをすることができませんでした場合でも。静的メソッドはコンパイル時に選択されます。それは動的に動作させるための唯一の方法は、(私が知っていることを)列挙型のクラスオブジェクトを渡すもちろんの反射を、使用することです。

あなたが呼び出すことができるようにしたいのでColor.fromString(...)、あなたは選択の余地はないが、各列挙クラスの静的メソッドとしてこれを宣言します。言ったことで、私はあなたのロジックから再利用することができ、ほとんどの検索コード(あなたはリフレクションを使用しない限り、再び、だ)だと思います。

検索ロジックを再利用するには、契約変更することができIBaseEnum、それが返すメソッド宣言にするenumVal値を。その横に、values()この方法は、列挙型クラス自体で呼び出すことができます。ここでは次のように見ることができるものです。

interface IBaseEnum {

    String enumVal();

    public static <T extends Enum<T> & IBaseEnum> T 
                 fromString(String strVal, T[] values) {

        if (strVal == null)
            return null;

        for (T myEnum : values) {
            if (myEnum.enumVal().equalsIgnoreCase(strVal)) {
                return myEnum;
            }
        }

        return null;
    }
}

そして、それは以下のような列挙型クラスにつながります。

enum Colour implements IBaseEnum {
    VAL1("string")
    ;

    private final String val;

    Colour(String v) {
        this.val = v;
    }

    @Override
    public String enumVal() {
        return this.val;
    }

    public static Colour fromString(String s) {
        return IBaseEnum.fromString(s, values());
    }
}

注意:場合enumVal()だけ列挙リテラルを返すように意図され、その後、あなただけ使用することにより、すべてのこの複雑さを取り除くことができvalueOf、すべての列挙型で利用可能な方法を。あなたの値の比較は、カスタム・ロジックを必要とする場合にのみ、これを行います。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=427287&siteId=1