Genericsの実行時型情報
Java Genericsの総称型はコンパイル時にのみ解釈され、バイトコードには総称型であったという痕跡すら残りません。
仕様的に残さないことになっているため、実行時に総称型オブジェクトの型パラメータを知る方法はありません。
Java5で型パラメータを使ったクラス中で、パラメータとして渡されたクラスによって振る舞いを変えようとか思ってたら、渡されたクラスが取れない。調べてたら上のブログを見つけました。そうか、できないのねん・・・・何か凄くやりきれない感じがする。これだったらGenericsをあまり使わないほうが良い気がしてきた。
以下、参考までに調べ始めの時に書いたテストケースです。
package test.jdk5.generics; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Date; import junit.framework.TestCase; public class ParameterizedTypeRuntimeTest extends TestCase { public static class ParameterizedRef<T> { public ParameterizedRef(T obj) { this.obj = obj; } public final T obj; } public void testParameterizedRef() { final ParameterizedRef<Date> ref = new ParameterizedRef<Date>( new Date()); // 宣言されているクラスのクラス名チェック assertEquals(this.getClass().getName() + "$ParameterizedRef", ParameterizedRef.class.getName()); // 宣言されているクラスと、オブジェクトのクラスが一致するかどうかをチェック assertEquals(ParameterizedRef.class, ref.getClass()); // // 何だかよく分かんないけど、parameterizationに関係しているっぽい名前なので取得。 final TypeVariable<Class<ParameterizedRef>>[] typeParameters = ParameterizedRef.class .getTypeParameters(); // 予想通り長さが1の配列で、その中身はパラメータ assertEquals(1, typeParameters.length); assertEquals("T", typeParameters[0].getName()); // // うーん、この辺よくわからん。 final Type[] bounds = typeParameters[0].getBounds(); assertEquals(1, bounds.length); assertEquals(Class.class, bounds[0].getClass()); // //どうやったら、refオブジェクトから、Dateクラスをゲットできるの??? } }