我正在阅读有关仿制药及其限制的内容。
无法创建类型参数的实例
您无法创建类型参数的实例。例如, 以下代码导致编译时错误:
public static <E> void append(List<E> list) { E elem = new E(); // compile-time error list.add(elem); }
作为一种变通方法,您可以创建一个类型参数的对象 反射:
public static <E> void append(List<E> list, Class<E> cls) throws Exception { E elem = cls.newInstance(); // OK list.add(elem); }
您可以按如下方式调用append方法:
List<String> ls = new ArrayList<>(); append(ls, String.class);
我有点困惑。我理解为什么它不被允许,因为新的E()会因为类型擦除而变成新的object(),但为什么在class.newInstance中不会发生同样的事情?我的意思是它使用类型参数E,所以不会最终出现同样的问题吗?有人可以解释一下(我知道我必须添加try-catch才能让它编译)。
提前致谢!
答案 0 :(得分:3)
正如您所注意到的,类型参数E
只是编译器使用的东西,它不是用泛型实例化的,不能在run-rime中使用。另一方面,参数 cls
是真实的。它是在运行时传入的对象,其中包含所有类型信息。 E
的类型 {召回cls
)中的Class<E> cls
将进行类型删除(毕竟,{{1} }只是另一个通用的)但对象 Class
将继承有关其类型的信息。
答案 1 :(得分:0)
它将起作用,因为调用该方法的程序员必须将Class<E>
实例作为参数传递(此类型的类型将在类型擦除之前的编译时检查)。此实例将能够在运行时调用正确的构造函数,因为它能够确定其运行时类型,如果没有第一个片段中的实际实例,这是不可能的。