ここには2つのジェネリック型があります。1つはコレクションのサブタイプ用で、もう1つはコレクションの要素タイプ用です。次のコードが機能します。
private static <C extends Collection<E>, E>
C create(Class<C> cls) throws Exception
{
return cls.newInstance();
}
使用例。警告はありません。
Class<LinkedList<String>> clazz = ...;
LinkedList<String> result = create(clazz);
問題は、どうやって入手するclazz
かということです。コンパイラを本当に一生懸命説得する必要があります。
List<String> list = new LinkedList<String>();
clazz = (Class<LinkedList<String>>)list.getClass();
clazz = (Class<LinkedList<String>>)(Class<?>)LinkedList.class;
型キャストを容易にするユーティリティメソッドを使用できます。
public static <C extends Collection, E, T extends Collection<E>>
Class<T> type(Class<C> classC, Class<E> classE)
{
return (Class<T>)classC;
}
//usage:
clazz = type(LinkedList.class, String.class);
result = create(clazz);
楽しみは再帰的です:
Class<LinkedList<LinkedList<String>>> clazz2;
LinkedList<LinkedList<String>> result2;
clazz2 = type(LinkedList.class, clazz);
result2 = create(clazz2);
しかし、ある時点で、このばかげたゲームをやめなければなりません。ジェネリックタイピングは、私たちを苦しめるのではなく、私たちを助けることになっています。面倒になりすぎてプログラムが読めなくなったら、ドロップしてください。私たちが何年も幸せに暮らしてきた生のタイプを使ってください。