简体   繁体   English

如何使用Java泛型将“ T”参数传递为方法参数?

[英]How do I pass the “T” argument to as a method parameter using Java generics?

I'm using JBoss 7.1.3 with Java 6. I'm having trouble trying to figure out what I need to substitute for “???” in the below code to get my method to work properly. 我在Java 6中使用JBoss 7.1.3。在尝试找出下面的代码中要替换“ ???”的方法时,我很难解决。 What I want is to instantiate an instance of my “T” class, invoking the generic constructor each time I instantiate the class. 我想要的是实例化“ T”类的实例,每次实例化该类时都调用泛型构造函数。 Below is the method … 下面是方法...

public class MyClass<T extends AbstractModel>
{

    public void myMethod()
    {
        …
        final HashMap<String, String> data = new HashMap<String, String>();
        final T item = getInstance(???, data);

    }


    private T getInstance(final Class<T> class1,
                  final HashMap<String, String> data)
    {
        T retObj = null;
        try
        {
            Constructor ct = class1.getDeclaredConstructor(HashMap.class);
            Object[] argList = new Object[1];
            argList[0] = data;
            retObj = (T) ct.newInstance(argList);
        } catch (Exception e)
        {
        }   // try
        return retObj;
    }   // getInstance

here is the constructor for my abstract model class … 这是我的抽象模型类的构造函数……

public abstract class AbstractDIDOModel 
{

    protected HashMap<String, String> data;

    AbstractModel(final HashMap<String, String> data) 
    { 
        this.data = data;
    }

MyClass should have the Class<T> passed in: MyClass应该将Class<T>传入:

public class MyClass<T extends AbstractModel>
{
    private final Class<T> type;

    public MyClass(Class<T> type) { this.type = type; }

    public void myMethod()
    {
        …
        final HashMap<String, String> data = new HashMap<String, String>();
        final T item = getInstance(type, data);

    }

Due to Type Erasure , no information of T exists at runtime and so you cannot obtain the type it refers to in most cases. 由于类型擦除 ,在运行时不存在T信息,因此在大多数情况下您无法获得其引用的类型。

Note also that Constructor is typed, so you can replace this: 还要注意, Constructor是键入的,因此可以替换为:

Constructor ct = class1.getDeclaredConstructor(HashMap.class);
//...
retObj = (T) ct.newInstance(argList);

With this: 有了这个:

Constructor<T> ct = class1.getDeclaredConstructor(HashMap.class);
//...
retObj = ct.newInstance(argList);

If your goal is to use Class<T> as a Factory, I would take a different approach however. 如果您的目标是将Class<T>用作工厂,那么我将采用另一种方法。 I would just accept a Factory<T> , where Factory<T> is an interface: 我只接受一个Factory<T> ,其中Factory<T>是一个接口:

public interface Factory<T extends AbstractModel> {
   T create(HashMap<String, String> data);
}

Then creators of MyClass<T> can just implement this simply, without having to resort to reflection: 然后, MyClass<T>创建者可以简单地实现此目的,而不必求助于反思:

Factory<ConcreteModel> factory = new Factory<ConcreteModel>() {
   @Override
   public ConcreteModel create(HashMap<String, String> data) {
        return new ConcreteModel(data);
   }
}

You can use a trick if your class has the type parameters set, because in that case the type information is available at runtime. 如果您的类设置了类型参数,则可以使用技巧,因为在这种情况下,类型信息在运行时可用。 You can capture it and store it in a member field. 您可以捕获它并将其存储在成员字段中。 Then you can use that field as the class inside your generic construction method. 然后,您可以将该字段用作通用构造方法中的类。

public abstract class AbstractDIDOModel<T> 
{

 private Class<?> persistentClass = (Class<?>) ((ParameterizedType)  this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

 private T getInstance(final HashMap<String, String> data)
    {
        T retObj = null;
        try
        {
            Constructor ct = persistentClass.getDeclaredConstructor(HashMap.class);
            Object[] argList = new Object[1];
            argList[0] = data;
            retObj = (T) ct.newInstance(argList);
        } catch (Exception e)
        {
        }   // try
        return retObj;
    }

Finally, declare your concrete classes as such: 最后,这样声明您的具体类:

public class MyClass<T extends AbstractModel>
{
   ....
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM