簡體   English   中英

將參數化類型作為參數傳遞給方法

[英]Pass parameterized type to method as argument

該類來自供應商庫:

public class JsonParser {
    public <T> T parse(String json, Class<T> type) { ... }
}

這些是我的模特:

public class Video {
    @Key
    private String title;
    public String getTitle() {
        return title;
    }
}

public class Response<TResult> {
    @Key
    private TResult result;
    public TResult getResult() {
        return result;
    }
    // ...
}

此代碼有效:

JsonParser parser = new JsonParser();
String json = "{ \"title\": \"Hello world\" }";
Video video = parser.parse(json, Video.class);

此代碼不起作用:( Response<Video>.class語法錯誤)

JsonParser parser = new JsonParser();
String json = "{ \"result\" : { \"title\": \"Hello world\" } }";
Response<Video> videoResponse = parser.parse(reader, Response<Video>.class);

此代碼有效:

public class VideoResponse extends Response<Video> {
}

...
JsonParser parser = new JsonParser();
String json = "{ \"result\" : { \"title\": \"Hello world\" } }";
Response<Video> videoResponse = parser.parse(reader, VideoResponse.class);

我的問題是:如何將Response<Video>類傳遞給parse方法作為參數而不創建像這樣的VideoResponse (在我的節目,也有類似的許多型號Video ,我不想重復我的代碼創建空類VideoResponseUserResponseCommentResponseActivityResponse等)

由於Java泛型的實現方式,在大多數情況下,通用信息在運行時會丟失。 這些所謂的可再生類型的例外之一是泛型類的具體擴展。 第一個例子:

public class Video {
    @Key
    private String title;
    public String getTitle() {
        return title;
    }
}

public class Response<TResult> {
    @Key
    private TResult result;
    public TResult getResult() {
        return result;
    }
    // ...
}

解析器無法反序列化result屬性,因為它無法確定它的類型(因為此信息在運行時不可用)。 基本上,解析只是看到java.lang.Object ,並且無法確定要實例化以將JSON數據拉入的類型。 我假設您已經懷疑是這種情況,因此嘗試進行此調用:

Response<Video> videoResponse = parser.parse(reader, Response<Video>.class);

在上面的行中,您試圖告訴解析器特定響應是使用Video參數化的,但遺憾的是Java沒有泛型類文字的語法,因此代碼無法編譯。

在你的第二個例子中:

public class VideoResponse extends Response<Video> {
}

Response<Video> videoResponse = parser.parse(reader, VideoResponse.class);

您已經創建了泛型類的具體擴展。 對於此類擴展,泛型類型信息在運行時可用,因此您的解析器可以確定實例化所需的內容以反序列化您的JSON數據。

所有這些都是您實際問題的背景信息:

我的問題是:如何將Response類作為參數傳遞給parse方法而不創建像這樣的VideoResponse

你忽略了你正在使用的JSON庫,但是在大多數流行的庫中,反序列化方法都有一個覆蓋版本,它接受通常所說的超類型令牌 超類型令牌基本上只是類的具體擴展,類似於我上面描述的。 例如,在Jackson中,您可以像這樣反序列化您的JSON:

Response<Video> response = new ObjectMapper().readValue(
    jsonString, // JSON data
    new TypeReference<Response<Video>>() {} // super type token, implemented by anonymous class
);

您應該檢查您的JSON庫文檔中的類似內容。

由於Java泛型類型的“類型擦除”,您應該明確使用類型轉換,如下所示:

Response<Video> videoResponse = (Response<Video>) parser.parse(reader, Response.class);

它會引入編譯警告,但沒關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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