首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在java中实例化泛型类型

在java中实例化泛型类型
EN

Stack Overflow用户
提问于 2010-03-13 00:15:06
回答 12查看 95.4K关注 0票数 65

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

注意:这可能看起来是一个微不足道的泛型问题。但我敢打赌..。不是。:)

假设我有如下的类声明:

代码语言:javascript
复制
public class Abc<T> {
    public T getInstanceOfT() {
       // I want to create an instance of T and return the same.
    }
}
EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2010-03-13 00:39:42

代码语言:javascript
复制
public class Abc<T> {
    public T getInstanceOfT(Class<T> aClass) {
       return aClass.newInstance();
    }
}

您必须添加异常处理。

您必须在运行时传递实际的类型,因为它在编译后不是字节码的一部分,所以如果不显式提供它,就无法知道它。

票数 76
EN

Stack Overflow用户

发布于 2010-03-13 00:22:34

在您发布的代码中,不可能创建T的实例,因为您不知道它是什么类型:

代码语言:javascript
复制
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>引用:

代码语言:javascript
复制
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>
{
}
票数 28
EN

Stack Overflow用户

发布于 2010-03-13 00:26:05

您所写的没有任何意义,Java中的泛型旨在为对象添加参数多态功能。

什么意思?这意味着您希望保留类的一些类型变量,以便能够将您的类与许多不同的类型一起使用。

但是你的类型变量T是一个在运行时解析的属性,Java编译器将编译你的类来证明类型安全,而不会试图知道哪种对象是T,所以它不可能让你在静态方法中使用类型变量。该类型与对象的运行时实例相关联,而public void static main(..)与类定义相关联,在该作用域中,T没有任何意义。

如果要在静态方法中使用类型变量,则必须将该方法声明为泛型(这是因为,如前所述,模板类的类型变量与其运行时实例相关),而不是类:

代码语言:javascript
复制
class SandBox
{
  public static <T> void myMethod()
  {
     T foobar;
  }
}

这是可行的,但当然不适用于main方法,因为无法以泛型的方式调用它。

JVM编辑:问题是由于类型擦除,只编译了一个泛型类并将其传递给。类型检查器只检查代码是否安全,然后因为它证明了它,所以所有类型的泛型信息都会被丢弃。

要实例化T,您需要知道T的类型,但它可以同时是多个类型,因此只需要最少反射的一种解决方案是使用Class<T>实例化新对象:

代码语言:javascript
复制
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());
    }
}

当然,这意味着您要实例化的类型:

  • 不是
  • 的基元类型,它具有默认构造函数

要使用不同类型的构造函数,您必须更深入地研究反射。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2434041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档