推論された型パラメータからClassを得る
出羽ブログ - 型推論のS2Containerラッパーより。以下の手順で、推論された型パラメータからそのClassを得ることができます。
- 型パラメータ「T」を受け取るようにして、型推論により実行時に「T」が特定されるようにします。
- さらに、可変長引数で「T」の配列を受け取るようにします。
- これにより、「T」の配列がメソッドに渡されてくるので、ここから「T」のClassを取得できます!
- なお、可変長引数なので呼び出し側は引数を省略できます。
こんなことができてしまうとは!これはすごい!
ということで、これを参考に(↑の理解があっているかの確認もかねて)こんなのを作ってみた。
/** * 代入先の型のインスタンスを生成する。 * * @param <T> 型。デフォルトコンストラクタを持つこと。 * @param src ※指定しないでください。 * @return インスタンス * @throws InstantiationException インスタンス化できなかった場合 * @throws IllegalAccessException アクセス権がない場合 */ static <T> T create( T... src ) throws InstantiationException, IllegalAccessException { Class<T> cl = (Class<T>) src.getClass().getComponentType(); return cl.newInstance(); }
サンプル。
// 空のArrayListを生成する ArrayList<String> list = create(); // 空のLinkedListを生成する LinkedList<String> list2 = create(); System.out.println( list.getClass() ); System.out.println( list2.getClass() );
実行結果です。左辺の型に応じたクラスのコンストラクタが呼ばれて、そのインスタンスが生成されています。おー。
class java.util.ArrayList class java.util.LinkedList
まぁ、これだけだと「型推論が効かないところで使うとObjectが生成されてしまう」とかいう問題はあるんですけどね。
//型推論が効かないところで使うとObjectが生成される。 System.out.println( create().getClass() ); // class java.lang.Object
んー、何かうまい使い方はないかなー。