Question about java generics

I am writing this query service that is supposed to work with pairs of predefined classes. However, it seems redundant to me that when using this service class, I need to pass both the class type and the class object. For example, to request a Contact object, I need to provide both Contact.class and both, for example the following:

lookupService = new MyLookupServiceImpl<Contact>(Contact.class); 

In this case, is there a way to initialize the class without passing it to "Contact.class"? The service class is as follows:

 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.

Thanks,

+4
source share
3 answers

The answer is NO. In java, due to the erasure type , there is no other way to output / get this information at runtime of another passing the type information as a Class<?> Instance.

+3
source

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:

 T obj = new T(); 

due to the implementation of Java generics (with type wiping).

Note that in your cls code, MyObjectBuilder<T> is passed, which is most likely the object that creates the new T instances. MyObjectBuilder<T> uses reflection to create a new instance of T , with an expression like:

 T obj = cls.newInstance(); 

See also: Create a new instance of T in Java

0
source

The ball is correct (+1), unfortunately. However, if you are using an Injection Dependency framework such as Guice , you can ask Guice to give you TypeLiteral, which is the type that you are interested in. You can 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! :)

0
source

All Articles