为了账号安全,请及时绑定邮箱和手机立即绑定

在java中实例化泛型类型

在java中实例化泛型类型

慕田峪4524236 2019-08-13 15:39:23
在java中实例化泛型类型我想在java中创建一个Generics Type对象。请建议我如何实现同样的目标。注意:这似乎是一个微不足道的泛型问题。但我敢打赌......事实并非如此。:)假设我有类声明:public class Abc<T> {     public T getInstanceOfT() {        // I want to create an instance of T and return the same.     }}
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

public class Abc<T> {
    public T getInstanceOfT(Class<T> aClass) {
       return aClass.newInstance();
    }}

您必须添加异常处理。

您必须在运行时传递实际类型,因为它不是编译后字节代码的一部分,因此没有明确提供它就无法知道它。


查看完整回答
反对 回复 2019-08-13
?
慕仙森

TA贡献1827条经验 获得超8个赞

在您发布的代码中,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具有默认构造函数,则可以调用newInstance()Class对象。

如果你是子类,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>{}


查看完整回答
反对 回复 2019-08-13
?
波斯汪

TA贡献1811条经验 获得超4个赞

你写的内容没有任何意义,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());
    }}

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

  • 不是原始类型

  • 它有一个默认的构造函数

要与不同类型的构造函数一起操作,您必须深入挖掘反射。


查看完整回答
反对 回复 2019-08-13
  • 3 回答
  • 0 关注
  • 840 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号