[英]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.