Reputation: 244
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:
lookupService = new MyLookupServiceImpl<Contact>(Contact.class);
In this case, is there a way to initialize Class without passing in "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,
Upvotes: 4
Views: 112
Reputation: 4748
Bala is correct (+1) unfortunately. 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:
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. Just an idea! :)
Upvotes: 0
Reputation: 206796
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).
Note that in your code, cls
is passed to MyObjectBuilder<T>
which is most likely an object that creates new instances of T
. MyObjectBuilder<T>
uses reflection to create a new instance of T
, with a statement like this:
T obj = cls.newInstance();
See also: Create new instance of T in Java
Upvotes: 0
Reputation: 108947
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.
Upvotes: 3