2014-09-27 87 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示例以獲得更好的想法。