简体   繁体   English

关于java泛型的问题

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM