2015-07-12 927 views
2

我有一個名爲TResultJava泛型調用返回的方法<T extends >對象

public class TResult<T extends MyEntity> { 

    public List<T> getEntityList() { 
     return entityList; 
    } 
} 

類和我有其他的靜態方法有些類返回它

public static TResult getAllEntities(final Class clazz, RouteFilter filter){ 
} 

現在,當我打電話getAllEntities我需要將其轉換爲MyEntity,否則我會收到警告(未檢查的賦值)。 我試圖改變方法簽名,它只能與

public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class clazz, RouteFilter filter) {} 

作品爲什麼我要指出的是T當它在TResult類簽名已經定義在getAllEntities方法擴展APIBaseEntity?

TResult<APIBaseEntity> allEntities = GeneralCRUD.getAllEntities(APIAccount.class, filter); 
+2

「MyEntity」和「APIBaseEntity」是否應該是同一個類?如果是的話,請編輯,如果不是,我猜後者擴展了前者,不是嗎?請澄清。 – Joffrey

回答

6

首先,你不應該使用原始類型*,它會幫助你理解你在用泛型類做什麼。

問自己這些問題:什麼班級是clazz?你回來什麼樣的TResult?提供的類是否應該定義類型參數TResult

如果答案是肯定的,以最後一個問題,那麼你很可能在尋找這樣的聲明:

public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class<T> clazz, RouteFilter filter) { 
    //... 
} 

這基本上將強制返回TResult<T>是同一類型T作爲提供clazz :您的方法的類型參數。這也消除了轉換爲你想要的返回類型的負擔,因爲編譯器現在已經知道了。

爲什麼我必須指出T在getAllEntities方法中擴展APIBaseEntity時,它已經在TResult類簽名中定義了?

如果你寫public <T> TResult<T> myMethod()T是一個通用型的你的方法,但不限制可言,因此它可以是任何東西。 TResult<T>不作爲您的方法的類型參數的約束。你必須自己明確地約束它,因爲你甚至可以限制它比TResult類更多(例如子類型爲APIBaseEntity)。

如果你不約束你的方法的類型參數,你會得到一個編譯錯誤/警告(不記得從我的頭頂),因爲它不適合TResult的類型參數聲明。


*注:原始類型是沒有自己的類型參數引用泛型類型,如ClassTResult而不是Class<T>TResult<T>

+0

@rails方法getAllEntities中參數clazz的用法是什麼? – gabrielgiussi

+1

@gabrielgiussi它是在OP的原始代碼中,我猜它被用在方法的內部代碼中以訪問數據庫中的右表,也可能用於構造實體對象。另外,在這裏,正是允許爲OP沒有使用的方法選擇正確的返回類型。我編輯在這方面更清晰。 – Joffrey

+0

但是,如果只是爲方法選擇正確的返回類型,是否真的有必要?它不會受到方法調用的限制嗎?像'TResult allEntities = GeneralCRUD.getAllEntities(filter); ' – gabrielgiussi