如何创建具有指定类型参数的列表? 例如:
LinkedList<Integer> list = createList(LinkedList.class, Integer.class);
我尝试为它创建一个方法,但该方法在创建新实例时不包含type参数。
public static <T, L extends List<T>> L createList(Class<L> listClazz, Class<T> valueClazz) throws Exception
{
return listClazz.getConstructor().newInstance();
//Instead of
// new L<T>();
//does
// new L();
}
我希望我的问题很清楚,谢谢你的帮助。
答案 0 :(得分:8)
你做不到。泛型在运行时没有业务,因此您无法使用反射在运行时创建参数化实例。在运行时,LinkedList<Intege>
只是LinkedList
。类型信息 - Integer
在编译时通过“类型擦除”被擦除。关键是,你为什么要这样做?
答案 1 :(得分:1)
//Instead of // new L<T>(); //does // new L();
两个“做”完全相同的事情。你怎么知道它“做”而不是另一个?类型参数是用于类型检查的编译时幻象。它们与代码“做”无关。要创建LinkedList<T>
的实例,您不需要知道T
是什么,因为它在类型擦除后并不存在。
我认为你遇到的问题与函数内部的代码无关,而是与方法的签名有关。事实上,该方法是按原样声明的,并且您要向其传递Class<LinkedList>
类型的表达式(LinkedList.class
的类型),L
必须为LinkedList
由于该方法返回L
,编译器必须考虑返回类型LinkedList
。这些都与方法中的代码无关。
如果希望将方法的返回类型视为LinkedList<Integer>
,则只需传入类型为Class<LinkedList<Integer>>
的表达式。简单吧?你如何得到Class<LinkedList<Integer>>
类型的表达式?例如,您可以(Class<LinkedList<Integer>>)(Class<?>)LinkedList.class
。
如果这看起来有些虚假,那是因为Class
基本上是运行时的东西 - 它允许从该类运行时创建对象。将它与Generics(编译时类型检查机制)一起使用从根本上是有缺陷的。任何类都只有一个类对象,例如LinkedList
。是LinkedList
还是LinkedList<Integer>
还是LinkedList<String>
?好吧,它可能就是所有这些,在某种意义上,newInstance()
方法可以创建它们中的任何一个(在运行时没有区别)。