簡體   English   中英

java方法中的兩種泛型類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM