私が働いている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()
見られません。
これは、列挙型で継承機能に正しい方法ですか?それ以外の場合は、どのように私は、私はすべての単一の列挙型のメソッドの同じセットをコピー/貼り付け、繰り返す必要はありませんので、列挙型のメソッドを継承することができますか?
あなたのコードは、その私が言及する必要があり、動作しないいくつかの理由があります:
String enumVal = null;
:IBaseEnum
インターフェースという、numVal
暗黙の取得public
、static
および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
、すべての列挙型で利用可能な方法を。あなたの値の比較は、カスタム・ロジックを必要とする場合にのみ、これを行います。