对java中的泛型和反射的限制

我正在阅读关于泛型及其限制的内容。

无法创建类型参数的实例

您不能创建类型参数的实例。 例如,下面的代码会导致编译时错误:

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来编译它)。

提前致谢!


正如你所指出的那样,类型参数E只是编译器使用的东西,它不是用泛型实例化的,不能在运行时使用。 另一方面,参数cls是真实的。 它是一个运行时传入的对象,其所有类型的信息都将被反映出来。 在cls类型中的E (回忆Class<E> cls )将被类型擦除(毕竟, Class只是另一个通用类型),但是对象cls将继承关于它的类型的信息。


这将起作用,因为调用该方法的程序员必须将Class<E>实例作为参数传递(此类型的实例在类型擦除前将在编译时检查)。 这个实例可以在运行时调用正确的构造函数,因为它可以确定它的运行时类型,如果没有第一个片段中的实际实例,这是不可能的。

链接地址: http://www.djcxy.com/p/76507.html

上一篇: Restrictions on Generics in java and reflection

下一篇: Overriding private methods in (non