[英]Question about java generics
I am writing this query service that's suppose to work with couple predefined classes. 我正在编写这个查询服务,它假设可以使用几个预定义的类。 However, it seems to me to be redundant that, when using this service class, I need to pass both the Type of the class and a class object it self.
但是,在我看来,在使用这个服务类时,我需要传递类的类和它自己的类对象。 For example, to query "Contact" object, I'll need to provide both and Contact.class, like the following:
例如,要查询“Contact”对象,我需要同时提供和Contact.class,如下所示:
lookupService = new MyLookupServiceImpl<Contact>(Contact.class);
In this case, is there a way to initialize Class without passing in "Contact.class"? 在这种情况下,有没有办法初始化类而不传入“Contact.class”? The service class look like the following:
服务类如下所示:
public class MyLookupServiceImpl<T> {
private Class<T> cls;
public MyLookupServiceImpl(Class<T> clz){
this.cls = clz;
}
public T queryObject(String sql) {
try {
QueryResult result = ConnectionFactory.getConnection().query(sql);
if(result.getSize()>0){
T obj=null;
MyObject sObj = result.getRecords()[0];
MyObjectBuilder<T> ob = new MyObjectBuilder<T>(cls);
obj = ob.buildORMObject(sObj);
return obj;
}
} catch (ConnectionException e) {
logger.warn(e.toString());
}
return null;
}
}
Any suggestion would be appreciated. 任何建议将不胜感激。
Thank you, 谢谢,
The answer is NO. 答案是不。 In java, because of type erasure , there is no other way infer/get this info at runtime other that passing in the type info as a
Class<?>
instance. 在java中,由于类型擦除 ,没有其他方法可以在运行时推断/获取此信息,而将类型信息作为
Class<?>
实例传递。
This is most likely necessary because it is not possible to create a new instance of an arbitrary class indicated by a type parameter; 这很可能是必要的,因为不可能创建由类型参数指示的任意类的新实例; in other words, you cannot do:
换句话说,你做不到:
T obj = new T();
because of the way Java generics are implemented (with type erasure). 因为Java泛型的实现方式(使用类型擦除)。
Note that in your code, cls
is passed to MyObjectBuilder<T>
which is most likely an object that creates new instances of T
. 请注意,在您的代码中,
cls
被传递给MyObjectBuilder<T>
,这很可能是创建T
新实例的对象。 MyObjectBuilder<T>
uses reflection to create a new instance of T
, with a statement like this: MyObjectBuilder<T>
使用反射来创建T
的新实例,其语句如下:
T obj = cls.newInstance();
See also: Create new instance of T in Java 另请参阅: 在Java中创建T的新实例
Bala is correct (+1) unfortunately. 不幸的是,巴拉是正确的(+1)。 However, if you use a Dependency Injection framework like Guice you could ask Guice to pass you a TypeLiteral which is the type you're interested in. You could do something like this:
但是,如果您使用像Guice这样的依赖注入框架,您可以让Guice向您传递一个TypeLiteral,这是您感兴趣的类型。您可以执行以下操作:
public class MyLookupServiceImpl<T> {
private Class<T> cls;
@Inject
public MyLookupServiceImpl(TypeLiteral<T> type){
this.cls = (Class<T>)type.getRawType();
}
}
Then use the Guice Injector to pass you instances of MyLookupServiceImpl. 然后使用Guice Injector为您传递MyLookupServiceImpl的实例。 Just an idea!
只是一个想法! :)
:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.