この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

クラスメンバーのメタ情報はイレイジャによって消されずに残る

これまで、Genericsのパラメータ型("Set"における"String"のこと)は、ランタイム時にはイレイジャによってすべて消されるものと思い込んでいました。(クラス除く)


しかし、どうやら"フィールド"および"メソッドの引数&戻り値"については、ランタイム時にパラメータ型を取得可能なようです。

import java.util.*;
import java.lang.reflect.*;

public class test {

    public static void main(String... args) throws Exception {
        final Method m = test.class.getMethod("listToSet", List.class);

        // 戻り値の宣言型
        final Type returnType = m.getGenericReturnType();
        // 引数の宣言型
        final Type[] argTypes = m.getGenericParameterTypes();

        // パラメータ付き宣言型(ParameterizedType)にキャストし、パラメータ型を取得する。
        System.out.println("return: " + ((ParameterizedType) returnType).getActualTypeArguments()[0]);
        System.out.println("arg: " + ((ParameterizedType) argTypes[0]).getActualTypeArguments()[0]);
    }

    public static Set<String> listToSet(List<String> list) {
        return new HashSet<String>(list);
    }
}


このコードの実行結果は

return: java.lang.String
arg: java.lang.String

です。キチンと取得できているようです。

そういえば

そういえば、イレイジャがパラメータ型の情報を消さないのって、当たり前ですよね。
だって、この情報を残しておかなかったら、もしライブラリ化して後から使う場合、型チェックができなくなるし。


こんなことに気がつかなかったのが恥ずかしい(-_-)