2016-09-22 52 views
3

我剛剛轉向使用Java泛型,因此我不確定是否我要求 是正確的問題。類<T>爲Java中的通用?

我試圖使用以下方法:

public <T> ResponseEntity<T> exchange(String url, 
            HttpMethod method, 
            HttpEntity<?> requestEntity, 
            Class<T> responseType, 
            Object... uriVariables) 
          throws RestClientException 

對於<T>型我已經提供了Response<MyDTO>,所以我的方法調用看起來像:

ResponseEntity<Response<MyDTO>> re = exchange(...) 

我無法工作,如何爲Class<T> responseType參數提供正確的值?

我知道java中的泛型經歷了類型擦除,因此您不應該能夠在運行時通過反射來確定類型,但我知道我想提供的確切類型。

我見過How to get a class instance of generics type T的許多變體,它們將傳遞類類型作爲構造函數參數。

但我無法弄清楚如何製作Class<Response<MyDTO>>的實例。

有沒有辦法做到這一點?或者是否有禁忌的仿製藥限制?

回答

2

或者在仿製藥中是否存在禁忌的限制?

是的。由於類型擦除,一般類型共享相同的運行時類的所有實例,即

new Response<FooDto>().getClass() == new Response<BarDto>().getClass() 

因爲同一類對象用於兩個類型參數,其類型不能約束該參數,即

new Response<FooDto>().getClass() 

的類型是

Class<? extends Response> 

同樣,Response<FooDto>.class不編譯的,因爲沒有用於該特定類型的無級對象,只有一類對象S在所有Response實例中都有。

從理論上講,你就可以躺在約類對象的類型,編譯器:這將彙編

Class c = Response.class 
Class<Response<FooDto>> clazz = (Class<Response<FooDto>>) c 

,但不太可能做你想做的在運行時,因爲被調用的方法將無法確定Response的類型參數。

這給我們留下了兩種可能性:API設計者搞砸了,並且使這個API不能用於你的用例,或者你使用的API錯誤。查找該方法的重載,該方法以不同的方式接受類型參數的值,並驗證您確實需要泛型。

+0

我實際上正在考慮一個特定的場景,它應該做你想做的事情(並且編輯我的答案以表明清楚),但是否則,是的。 –

0

出於某種原因,採取的Response<MyDTO>一個實例,並使用getClass()不會編譯通常的做法:

Response<MyDTO> response = new Response<MyDTO>(...); 
Class<Response<MyDTO>> clazz = response.getClass(); 

正如@meriton它會導致cannot convert from Class<capture#1-of ? extends Response> to Class<Response<MyDTO>>提及。

P.S .:期望Class作爲一個參數是非常不尋常的,我不知道他們需要什麼。

PPS:我測試了它和兩@ AlexeyRomanov和我的解決方案似乎並沒有產生 「泛型」 類:

import java.util.ArrayList; 

class Main 
{ 
    public static void main (String [] args) 
    { 
     System.out.println((Class<ArrayList<String>>)(Object)(ArrayList.class)); 
     System.out.println((new ArrayList<String>()).getClass()); 
    } 
} 

輸出

class java.util.ArrayList 
class java.util.ArrayList 

好像兩次泛型會丟失。如果這不僅僅是Class.toString的問題,那麼只需使用Response.class即可得到相同的結果。

+0

可能調用'newInstance()'或'getConstructor(...)。newInstance(...)'。 –

+0

您的代碼無法編譯:「類型不匹配:無法從類轉換爲類<響應>」 – meriton

+0

@meriton您是對的,我編輯了我的答案。 –

2

Response<whatever>的等級是Response.class。但是,要告訴編譯器,您希望它是Response<MyDTO>的類,具體而言,您必須將其轉換爲:(Class<Response<MyDTO>>) (Object) Response.class。如果演員對你產生懷疑......好吧,這是一件可疑的事。

這將實現預期的是,如果該參數被用來創建Response一個新實例,不需要創建MyDTO一個新實例(例如,假設用戶調用exchange後將其設置)。但我想不出其他情況。