我想在java中创建一个泛型类型的对象。请建议我如何实现同样的目标。
注意:这可能看起来是一个微不足道的泛型问题。但我敢打赌..。不是。:)
假设我有如下的类声明:
public class Abc<T> {
public T getInstanceOfT() {
// I want to create an instance of T and return the same.
}
}
发布于 2010-03-13 00:39:42
public class Abc<T> {
public T getInstanceOfT(Class<T> aClass) {
return aClass.newInstance();
}
}
您必须添加异常处理。
您必须在运行时传递实际的类型,因为它在编译后不是字节码的一部分,所以如果不显式提供它,就无法知道它。
发布于 2010-03-13 00:22:34
在您发布的代码中,不可能创建T
的实例,因为您不知道它是什么类型:
public class Abc<T>
{
public T getInstanceOfT()
{
// There is no way to create an instance of T here
// since we don't know its type
}
}
当然,如果您有一个对Class<T>
的引用,并且T
有一个默认的构造函数,那么只需在Class
对象上调用newInstance()
即可。
如果你将Abc<T>
子类化,你甚至可以绕过类型擦除问题,而不需要传递任何Class<T>
引用:
import java.lang.reflect.ParameterizedType;
public class Abc<T>
{
T getInstanceOfT()
{
ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
Class<T> type = (Class<T>) superClass.getActualTypeArguments()[0];
try
{
return type.newInstance();
}
catch (Exception e)
{
// Oops, no default constructor
throw new RuntimeException(e);
}
}
public static void main(String[] args)
{
String instance = new SubClass().getInstanceOfT();
System.out.println(instance.getClass());
}
}
class SubClass
extends Abc<String>
{
}
发布于 2010-03-13 00:26:05
您所写的没有任何意义,Java中的泛型旨在为对象添加参数多态功能。
什么意思?这意味着您希望保留类的一些类型变量,以便能够将您的类与许多不同的类型一起使用。
但是你的类型变量T
是一个在运行时解析的属性,Java编译器将编译你的类来证明类型安全,而不会试图知道哪种对象是T
,所以它不可能让你在静态方法中使用类型变量。该类型与对象的运行时实例相关联,而public void static main(..)
与类定义相关联,在该作用域中,T
没有任何意义。
如果要在静态方法中使用类型变量,则必须将该方法声明为泛型(这是因为,如前所述,模板类的类型变量与其运行时实例相关),而不是类:
class SandBox
{
public static <T> void myMethod()
{
T foobar;
}
}
这是可行的,但当然不适用于main
方法,因为无法以泛型的方式调用它。
JVM编辑:问题是由于类型擦除,只编译了一个泛型类并将其传递给。类型检查器只检查代码是否安全,然后因为它证明了它,所以所有类型的泛型信息都会被丢弃。
要实例化T
,您需要知道T
的类型,但它可以同时是多个类型,因此只需要最少反射的一种解决方案是使用Class<T>
实例化新对象:
public class SandBox<T>
{
Class<T> reference;
SandBox(Class<T> classRef)
{
reference = classRef;
}
public T getNewInstance()
{
try
{
return reference.newInstance();
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public static void main(String[] args)
{
SandBox<String> t = new SandBox<String>(String.class);
System.out.println(t.getNewInstance().getClass().getName());
}
}
当然,这意味着您要实例化的类型:
要使用不同类型的构造函数,您必须更深入地研究反射。
https://stackoverflow.com/questions/2434041
复制相似问题