2014-09-27 150 views
0

我遇到了解如何调用一个通用的实体服务的麻烦。下面的代码工作,但我需要维护getEntityClass()每个豆,我认为是完全多余的。如何从Java泛型类推断类?

public abstract class BaseEntityBean<T extends BaseEntity> extends BaseBean { 

    protected void loadEntity(Class<T> entityClass, Long entityId) { // entityClass same as T 
     T entity=genericEntityService.getEntity(entityClass, entityId); 
    } 

我们不要更改genericEntityService.getEntity(Class, Long)的签名。

我想的loadEntity签名更改为loadEntity(Long entityId)

如何在loadEntity(Long)范围内调用genericEntityService.getEntity(Class, Long)T推断实体类?

如果这个问题不明确,这里就是我想达到的目标:

public abstract class BaseEntityBean<T extends BaseEntity> extends BaseBean { 

    protected void loadEntity(Long entityId) { 
     T entity=genericEntityService.getEntity(T, entityId); // pseudo code 
    } 

目前的解决方案

protected void loadEntity(Long entityId) { 
    ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); 
    @SuppressWarnings("unchecked") 
    Class<T> clazz = (Class<T>) (superclass).getActualTypeArguments()[0]; 
    T entity=genericEntityService.getEntity(clazz, entityId); 
} 

我很高兴这一点,因为它让我通过。在路上,我会使实体服务类型友好,一切都应该妥善落实。

+3

纠正我,如果我错了,但就是因为类型擦除的不是这个不可能的?在运行时,T将是BaseEntity而不是实际的子类型。 – 2014-09-27 02:39:04

+0

它通过反射是可能的,但成本高,普遍不理想 – drewmoore 2014-09-27 03:02:17

+0

库鲁,你可能指的是第一个参数调用getEntity()。这不会编译,因此我对伪代码发表了评论。我只是为了说明我想达到的目的。我相信程序员比英语更好地理解代码。 :) – jacekn 2014-09-27 03:20:09

回答

0

还有就是要做到这一点使用反射的选项。 正如一些人指出的那样,这会增加一些开销,所以使用它明智。

protected final Class<T> getEntityClass() { 
    ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); 
    Class<T> clazz = (Class<T>) (superclass).getActualTypeArguments()[0]; 
    return clazz; 
} 
+0

肯定比我迄今为止更好。反射会增加一些开销,但在我的情况下,这根本不是问题。我会等一天。如果没有人解决从T推断类型的问题,我会接受你的答案。谢谢。 – jacekn 2014-09-27 03:06:58

+0

@jacekn你说得对。 – 2014-09-27 03:54:41

0

使用TypeTools

// From within the BaseEntityBean impl 
Class<?> t = TypeResolver.resolveRawArgument(BaseEntityBean.class, getClass()); 

使用TypeTools和getClass().getGenericSuperclass方法之间的区别是,TypeTools会走的全类型层次对你来说,完全解决T的值,即使它是几层下来在这种情况下,getClass().getGenericSuperclass失败。请参阅Generic DAO示例以获得更好的想法。