为什么工厂模式中的包装类型参数适用于类型擦除?

时间:2018-01-29 17:12:22

标签: java generics

来自https://stackoverflow.com/a/75254/156458

你不能做新的E"。但你可以把它改成

 private static class SomeContainer<E>
 {
     E createContents(Class<E> clazz)
     {
         return clazz.newInstance();
     }
 }

这是一种痛苦。但它的确有效。将其包装在工厂模式中  它更容易忍受。

我想知道为什么这个方法有效?

为什么不键入删除适用于Class<E> clazz,因此它变为Class<Object> clazz,然后clazz.newInstance()会返回Object的实例?

感谢。

2 个答案:

答案 0 :(得分:1)

类型擦除确实适用于Class<E>,但它在运行时变为Class。但它仍然是在运行时传递给方法的特定类的Class对象。

newInstance() method返回其类型参数,此处为E,因此编译器知道它将返回正确的类型。但是newInstance方法在运行时在JVM中返回Object

在调用代码中,编译器将强制转换插入到正确的类型,该类型基于调用代码中的E。例如。代码:

Foo f = new EnclosingClass.SomeContainer<Foo>().createContents(Foo.class);

&#34;看起来像&#34;这在JVM中:

Foo f = (Foo) new EnclosingClass.SomeContainer().createContents(Foo.class);

这里的工厂模式只是使用Class对象来提供运行时类型。

答案 1 :(得分:1)

类型删除并不意味着clazz变为Class<Object>。这意味着它变成了一个普通的,朴素的Class实例。 newInstance方法将始终调用类对象表示的类型的构造函数,因为这是它的整个目的。在功能上,Class对象所代表的类型根本不在泛型中编码。你可以通过记住Class个对象和newInstance在Java 1.5首先引入泛型之前工作得很好来直觉。