[英]Two generic types in java method
我正在使用retrofit2構建一些同步json代理。
我的服務器的響應始終采用以下格式:
{status:code, something:{complex object}}
所以我有:
public class BasicResponse<T> {
private T data;
@SerializedName("status")
private String status;
}
我的解析器有一個映射,可以動態定義類型並根據服務器響應中“某物”的名稱創建BasicResponse<T>
實際上,一切工作正常,當“某物”返回我正在使用數組的對象列表時。
但是我想將數組更改為任何類型的集合,並且我真的不想更改解析器,所以我創建了一個方法:
private <U> BasicResponse<U> handleResponse(Response<? extends BasicResponse<U>> resp){
BasicResponse handledResponse = null;
if (resp != null && resp.isSuccessful() && resp.body() != null) {
resp.body();
if(handledResponse.getData().getClass().isArray())
handledResponse.setData(Arrays.asList(handledResponse.getData()));
//a lot of others stuff
return handledResponse;
}
在這種方法中,我想獲取一些“ resp”作為BasicResponse<User[]>
並將其轉換為BasicResponse<List<User>>
但是由於List<User>
與User[]
不同,因此Java無法編譯返回值,因此我需要具有兩個可以相同或不相同的泛型類型。
可能嗎?
因此,如果我對它的理解正確,則希望一個方法能夠處理類型為BasicResponse輸入的數組和原子元素的混合,但返回值始終是類型為BasicResponse的List。
您不能使用類型參數(代碼中的U)將組件類型從輸入綁定到返回。 原因是X和X [](無論X是什么)都沒有一個公共的超類,該類將排除任何其他類型的響應數據。
一種解決方法是提供將輸入類型轉換為輸出類型的lambda,如下所示:
private <U,V> BasicResponse<U> handleResponse(final Response<BasicResponse<V>> resp, final Function<U, V> cast) {
if (resp == null || !resp.isSuccessful() || resp.body() == null)
return null;
else
return new BasicResponse<>(cast.apply(resp.body().getData()));
}
...
Response<BasicResponse<String[]>> arrayResp = ...;
BasicResponse<List<String>> listBasicResp =
handleResponse(arrayResponse, (v) -> Arrays.asList(v));
...
Response<BasicResponse<String>> atomicResp = ...;
BasicResonse<List<String>> listBasicResp2 =
handleResponse(atomicResponse, (v) -> Collections.singletonList(v));
請注意,只要一個人提供適當的lambda來進行翻譯,就可以為輸入和結果基本響應混合不同的組件類型。 我要說的是,在大多數情況下這不是問題,實際上,即使您不方便使用一種方法,也不會阻止用戶代碼進行此類翻譯。
如果要為綁定組件類型的這兩種特定情況提供預制方法,則可以簡單地添加幾個附加的handleResponse方法,這些方法在上述方法中委托並提供適當的lambda:
private <U> BasicResponse<List<U>> handleSingleObjectResponse(final Response<BasicResponse<U>> resp) {
return handleResponse(resp, (v) -> Collections.singletonList(v));
}
private <U> BasicResponse<List<U>> handleArrayResponse(final Response<BasicResponse<U[]>> resp) {
return handleResponse(resp, (v) -> Arrays.asList(v));
}
請注意,您不能像擦除后一樣重載相同的方法名稱,因為它們都共享簽名:(響應)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.