[英]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
,我不想重復我的代碼創建空類VideoResponse
, UserResponse
, CommentResponse
, ActivityResponse
等)
由於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.