我们这里有两种泛型类型,一种用于集合的子类型,一种用于集合的元素类型。以下代码可以工作:
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);
但在某个时候,我们必须停止这种愚蠢的游戏。泛型类型应该帮助我们,而不是折磨我们。当它变得太麻烦并且使我们的程序无法阅读时,就放弃它。使用我们多年来快乐生活的该死的原始类型。