关于java泛型的问题

时间:2011-05-10 20:30:14

标签: java generics reflection

我正在编写这个查询服务,它假设可以使用几个预定义的类。但是,在我看来,在使用这个服务类时,我需要传递类的类和它自己的类对象。例如,要查询“Contact”对象,我需要提供两者和Contact.class,如下所示:

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

在这种情况下,有没有办法初始化Class而不传入“Contact.class”? 服务类如下所示:

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;
}
}

任何建议都将不胜感激。

谢谢,

3 个答案:

答案 0 :(得分:3)

答案是否定的。在java中,由于type erasure,除了将类型信息作为Class<?>实例传递之外,没有其他方法可以在运行时推断/获取此信息。

答案 1 :(得分:0)

这很可能是必要的,因为无法创建由类型参数指示的任意类的新实例;换句话说,你做不到:

T obj = new T();

因为Java泛型的实现方式(使用类型擦除)。

请注意,在您的代码中,cls会传递给MyObjectBuilder<T>T很可能是创建MyObjectBuilder<T>新实例的对象。 T使用反射创建T obj = cls.newInstance(); 的新实例,其语句如下:

{{1}}

另请参阅:Create new instance of T in Java

答案 2 :(得分:0)

不幸的是,巴拉是正确的(+1)。但是,如果您使用像Guice这样的依赖注入框架,您可以让Guice通过您感兴趣的类型TypeLiteral。您可以这样做:

public class MyLookupServiceImpl<T> {
    private Class<T> cls;

    @Inject
    public MyLookupServiceImpl(TypeLiteral<T> type){
        this.cls = (Class<T>)type.getRawType();
    }
}

然后使用Guice Injector传递MyLookupServiceImpl的实例。只是一个想法! :)