2015-01-11 7 views
5

Enumを継承する制限付きのパラメータをとる汎用メソッドを記述したいと思います。例えば、私は列挙型を持っている場合は、次のように:バインドされたエクステンションを持つ汎用メソッドEnumパラメータ - values()メソッドにアクセスできない

public enum InputFlags{ 
    ONE (0000001), 
    TWO (0000002), 
    THREE (00000004); 

    public final int value; 

    InputFlags(int value){ 
     this.value = value; 
    } 
} 

は、私はその後、次の操作を行うことができます。

​​

しかし、私はそのリターンパラメータ囲まれている一般的な方法で上記を実行しようとすると、私は一般的な方法でvalues()にアクセスすることができないかのように

public static <T extends Enum> T getFlags(int f){ 
     T.values(); // NOT allowed, even though I have bounded by extending Enum. 
} 

それはそうです:私はvalues()メソッドにアクセスすることはできません。これはEnumsの特異なのですか、それともこれの道でしょうか?

+0

ようです。 – Holger

答えて

0

これは、のstaticの方法です。これは、の特質です。ジェネリックスやその他の方法で、Javaにはstaticのメソッドに適用されるインタフェースを定義する方法はありません。クラスはstaticメソッドを実装する必要があり/実装する必要があります。

また、erasureなどのタイプの変数は、という型変数を、メソッド呼び出し式staticの型名として使用できないようにします。

+0

'static 'キーワードを取り除くと、私はまだ同じ問題を抱えています。 – Kerry

+0

@kerry 'values'はあなたの' getFlags'ではなく 'static'メソッドです。 –

+0

私は 'static'キーワードについて誤解しました。私は自分の頭でこれを動かすことができないので、あなたの答えについて考える必要があります。私の(単純な)ビューでは、ジェネリックメソッドのパラメータをenumにバインドしていたので、静的または非静的なすべてのenumメソッドが使用可能になるはずです。 – Kerry

1

values()は、InputFlagsクラスのコンパイラによって挿入された静的メソッドです。したがって、T.values()を使用することはできません。特に、Tは汎用タイプです。ただし、のTオブジェクト(通常はgetClass()経由、またはgetFlags(int f, Class<T> clazz)への渡し)を取得できる場合は、そのオブジェクトに対してClass#getEnumConstants()を使用できます。

+0

私はパラメータを 'Enum'にバインドしているので、なぜそれが利用できないのかということを頭に浮かべることはできません。私はこれをしばらく考えなければならないと思います。 – Kerry

+0

values()はEnumのすべてのサブクラスで静的メソッドですが、Enum自体のメソッドではありません。したがって、コンパイラはEnumのメンバとしてメソッドを見つけることができません。さらに、静的メソッド(つまり、そのクラスに属しているクラス)の場所はコンパイル時に解決されますが、ここではこれを行うことはできません。 – Clashsoft

8

values()は、Javaでは非常に奇妙なことです。ドキュメント内のEnumを参照してください - values()もありません! values()は、Enumの方法ではありません。代わりに、values()と呼ばれるstaticメソッドが、Enumを拡張するすべてのクラスに暗黙的に追加されます。しかし、enumのためのvalues()の方法は、別のenumvalues()の方法とは異なります。

T extends Enumt場合は、あなたがtEnumからインスタンスメソッドを呼び出すことができますT型を持つことを意味しているという事実。あなたはEnumstaticメソッドを呼び出すことはできません(そして、あなたは、values()はとにかく存在しない可能性があっても!)

values()を名前で実際のenumがわかっている場合にのみ有効です。タイプパラメータTしか持っていない場合は使用できません。

この問題を回避する方法は、Classオブジェクトを渡すことです。このように:あなたは[ `EnumSet`](http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html)を再発明されているよう

public static <T extends Enum<T>> T getFlags(Class<T> clazz, int f){ 
    T[] array = clazz.getEnumConstants(); // This is how you can get an array. 
    Set<T> set = EnumSet.allOf(clazz);  // This is how you can get a Set.  
} 
関連する問題