下記のとおり一般的な方法は:ジェネリックメソッド有界型パラメータと型消去
私は消去時に推定static <E, K extends E> void someMethod(K k, E[] e) {}
、消去タイプは次のようになります。どのようにでしょうtypeパラメータ
static void someMethod(Object k, Object[] e) {}
興味があるだけタイプ消去後の制約を知っていますか?その型パラメータKはE?
下記のとおり一般的な方法は:ジェネリックメソッド有界型パラメータと型消去
私は消去時に推定static <E, K extends E> void someMethod(K k, E[] e) {}
、消去タイプは次のようになります。どのようにでしょうtypeパラメータ
static void someMethod(Object k, Object[] e) {}
興味があるだけタイプ消去後の制約を知っていますか?その型パラメータKはE?
あなたは消去について正しいです。実際には、ランタイムは制約について知らない。コンパイラのみが行います。
あなたのタイプ消去された署名は正しいです。ただし、メソッドの制約はコンパイル時に消去されません。コンパイル時に使用されるメタデータにエンコードされます(リフレクション*でアクセスできますが、通常は実行時には使用されません)。その後、あなたはget(...)
メソッドを呼び出すことになりますあなたがString
とArrayList
をパラメータあれば、あなたのコードでは、
public Object get(int index)
しかし:
public E get(int index)
型消去して次のようになります。たとえば、クラスjava.util.ArrayList<E>
はメソッドを持っていますタイプ消去にもかかわらず、結果をString
にキャストする必要はありません。
これは、クラスまたはメソッド呼び出しをパラメータ化するときとは異なります。提供されたパラメータ化は、コンパイル時に完全に消去されたです。たとえば:
*
ArrayList myList = new ArrayList();
が
java.lang.reflect.Type
インスタンスを返す反射法を使用して行うことができる反射を経由して、実行時にこの情報へのアクセス:コンパイル後
ArrayList<String> myList = new ArrayList<String>();
は同等です。たとえば、実行時にメソッドの制約を取得するには、java.lang.reflect.Method
のgetGenericParameterTypes()
メソッドを呼び出すことができます。この返された情報を処理することにより、実行時に制約を判別することができます。
私は実際には、あなたのタイプの制約
static <E, K extends E> void someMethod(K k, E[] e) {}
が
static void someMethod(Object k, Object[] e) {}
として(コンパイル時)正確同じ効果があり、それを注意したいあなたはドンが」someMethod("foo", new Integer[3])
を呼び出して試してみてください私を信じていない。コンパイラは、E
とK
両方のパラメータとしてObject
を推測することが有効であるため
これは(任意K
オブジェクトもObject
のインスタンスであり、そして任意E[]
オブジェクトもObject[]
のインスタンスであるため(その配列を覚えています型はJavaでは共変です))。
これはJava Genericsの一般的な落とし穴です。たとえば、Arrays.fill()
メソッドのシグニチャはstatic void fill(Object[] a, Object val)
です。それをさらに制限することはできません。
それ以外の場合はあまり消去されません。 –