为什么我们可以在Java中创建泛型模板而不是泛型类型的新实例?
我知道不可能做到:为什么我们可以在Java中创建泛型模板而不是泛型类型的新实例?,java,generics,Java,Generics,我知道不可能做到: new T其中T由于类型擦除而为泛型类型 那么,为什么可以做一些类似于newa的事情,其中T是泛型的?例如,为什么要编译下面的代码 static class A<T>{ T t; A(T t){ this.t=t; } } static class B<T>{ A<T> create(T t){ return new A<T>(t); } } publ
new T
其中T
由于类型擦除而为泛型类型
那么,为什么可以做一些类似于newa
的事情,其中T是泛型的?例如,为什么要编译下面的代码
static class A<T>{
T t;
A(T t){
this.t=t;
}
}
static class B<T>{
A<T> create(T t){
return new A<T>(t);
}
}
public static void main (String[] args) throws java.lang.Exception
{
A<Integer> a = new B<Integer>().create(3);
}
静态A类{
T;
A(T){
t=t;
}
}
静态B类{
A创建(T){
返回新的A(t);
}
}
公共静态void main(字符串[]args)引发java.lang.Exception
{
A=新的B()。创建(3);
}
因为A
在编译和运行时都是定义良好的类型
在概念上的中间步骤,在:
new B<Integer>()
擦除后,A
变为A
,这是一种有效类型
您不能执行newt
,因为t
不是一个定义良好的类型,它只是一个标记。如果您确实需要,您可以获得相应的类并使用以下方法实例化T
类型的对象:
public class GenericFactory {
<T> T create(Class<T> c) throws Exception {
return c.newInstance();
}
}
是的,这很难看。由于类型擦除,您可以实例化新的A()
。如果Java将泛型实现为可修改的,那么如果没有用于查找T
的运行时绑定的反射,这将不起作用
通过扩展,这是由于对象类型的非泛型方面是具体化的(可通过getClass()
访问),编译器不可能发出这样的字节码,根据调用站点,它将能够实例化任何类型T。您没有创建泛型模板的新实例。您正在使用常规模板创建对象的实例
new A<T>(t);
新的A(t);
创建一个新的a
,它不是通用的。您不一定知道编译时T
将是什么,但您知道对象将是A
。事实上,它的美妙之处在于,您不必预测T
将是什么,这允许您创建这样强大的代码,并且可以重用。想象一下,如果您实现了一个堆栈
,那么您对实际的内容类型不感兴趣。您有兴趣很好地处理top
、pop
、push
操作。如果不必预测元素是整数
、字符串
还是其他类型,则可以优雅地编写适用于许多不同类的通用代码
如果我必须预测什么是T
,那么我宁愿说它是一个对象
,并且能够处理任何对象。我相信事实上,类似的事情会在后台发生。另外,另一种选择是使用反射
,但这一点也不干净
new GenericFactory().create(Integer.class);
new A<T>(t);