猿问

在java中实例化泛型类型

在java中实例化泛型类型

我想在java中创建一个Generics Type对象。请建议我如何实现同样的目标。

注意:这似乎是一个微不足道的泛型问题。但我敢打赌......事实并非如此。:)

假设我有类声明:

public class Abc<T> {
    public T getInstanceOfT() {
       // I want to create an instance of T and return the same.
    }}


慕田峪4524236
浏览 776回答 3
3回答

潇湘沐

public&nbsp;class&nbsp;Abc<T>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;getInstanceOfT(Class<T>&nbsp;aClass)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;aClass.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;}}您必须添加异常处理。您必须在运行时传递实际类型,因为它不是编译后字节代码的一部分,因此没有明确提供它就无法知道它。

慕仙森

在您发布的代码中,T由于您不知道它是什么类型,因此无法创建实例:public&nbsp;class&nbsp;Abc<T>{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;getInstanceOfT() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;There&nbsp;is&nbsp;no&nbsp;way&nbsp;to&nbsp;create&nbsp;an&nbsp;instance&nbsp;of&nbsp;T&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;since&nbsp;we&nbsp;don't&nbsp;know&nbsp;its&nbsp;type &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}}当然,如果您有一个引用Class<T>并且T具有默认构造函数,则可以调用newInstance()该Class对象。如果你是子类,Abc<T>你甚至可以解决类型擦除问题,并且不必传递任何Class<T>引用:import&nbsp;java.lang.reflect.ParameterizedType;public&nbsp;class&nbsp;Abc<T>{ &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;getInstanceOfT() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParameterizedType&nbsp;superClass&nbsp;=&nbsp;(ParameterizedType)&nbsp;getClass().getGenericSuperclass(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class<T>&nbsp;type&nbsp;=&nbsp;(Class<T>)&nbsp;superClass.getActualTypeArguments()[0]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;type.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;e) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Oops,&nbsp;no&nbsp;default&nbsp;constructor &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;RuntimeException(e); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;instance&nbsp;=&nbsp;new&nbsp;SubClass().getInstanceOfT(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(instance.getClass()); &nbsp;&nbsp;&nbsp;&nbsp;}}class&nbsp;SubClass &nbsp;&nbsp;&nbsp;&nbsp;extends&nbsp;Abc<String>{}

波斯汪

你写的内容没有任何意义,Java中的泛型旨在将参数多态的功能添加到对象中。这是什么意思?这意味着您希望保持类的某些类型变量未定,以便能够使用具有许多不同类型的类。但是你的类型变量&nbsp;T是一个在运行时解析的属性,Java编译器将编译你的类证明类型安全而不试图知道什么类型的对象,T所以它不可能让你在静态方法中使用一个类型变量。该类型与对象的运行时实例public void static main(..)相关联,同时与类定义相关联,并且在该范围内T并不意味着什么。如果要在静态方法中使用类型变量,则必须将该方法声明为泛型(这是因为,如解释的模板类的类型变量与其运行时实例相关),而不是类:class&nbsp;SandBox{ &nbsp;&nbsp;public&nbsp;static&nbsp;<T>&nbsp;void&nbsp;myMethod() &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;foobar; &nbsp;&nbsp;}}这是有效的,但当然不是用main方法,因为没有办法以通用方式调用它。编辑:问题是因为类型擦除只编译一个泛型类并传递给JVM。类型检查器只是检查代码是否安全,然后因为它证明了它被丢弃了所有类型的通用信息。要实例化T你需要知道它的类型T,但它可以同时是多种类型,因此只需要最少量反射的一个解决方案就是Class<T>用来实例化新对象:public&nbsp;class&nbsp;SandBox<T>{ &nbsp;&nbsp;&nbsp;&nbsp;Class<T>&nbsp;reference; &nbsp;&nbsp;&nbsp;&nbsp;SandBox(Class<T>&nbsp;classRef) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference&nbsp;=&nbsp;classRef; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;getNewInstance() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;reference.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;e) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SandBox<String>&nbsp;t&nbsp;=&nbsp;new&nbsp;SandBox<String>(String.class); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(t.getNewInstance().getClass().getName()); &nbsp;&nbsp;&nbsp;&nbsp;}}当然这意味着您要实例化的类型:不是原始类型它有一个默认的构造函数要与不同类型的构造函数一起操作,您必须深入挖掘反射。
随时随地看视频慕课网APP

相关分类

Java
我要回答