Jac*_*Dam 3 java generics reflection
这个类来自供应商库:
public class JsonParser {
public <T> T parse(String json, Class<T> type) { ... }
}
Run Code Online (Sandbox Code Playgroud)
这些是我的模型:
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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
此代码有效:
JsonParser parser = new JsonParser();
String json = "{ \"title\": \"Hello world\" }";
Video video = parser.parse(json, Video.class);
Run Code Online (Sandbox Code Playgroud)
此代码不起作用:(语法错误Response<Video>.class)
JsonParser parser = new JsonParser();
String json = "{ \"result\" : { \"title\": \"Hello world\" } }";
Response<Video> videoResponse = parser.parse(reader, Response<Video>.class);
Run Code Online (Sandbox Code Playgroud)
此代码有效:
public class VideoResponse extends Response<Video> {
}
...
JsonParser parser = new JsonParser();
String json = "{ \"result\" : { \"title\": \"Hello world\" } }";
Response<Video> videoResponse = parser.parse(reader, VideoResponse.class);
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何将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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
解析器将无法反序列化该result属性,因为它将无法确定它是什么类型(因为此信息在运行时不可用)。基本上,解析只看到java.lang.Object,并不能确定实例化的类型以将 JSON 数据拉入。我假设您已经怀疑是这种情况,因此尝试拨打此电话:
Response<Video> videoResponse = parser.parse(reader, Response<Video>.class);
Run Code Online (Sandbox Code Playgroud)
在上面的行中,您试图告诉解析器特定的响应是用 参数化的Video,但不幸的是,Java 没有通用类文字的语法,因此代码无法编译。
在你的第二个例子中:
public class VideoResponse extends Response<Video> {
}
Response<Video> videoResponse = parser.parse(reader, VideoResponse.class);
Run Code Online (Sandbox Code Playgroud)
您已经创建了泛型类的具体扩展。对于此类扩展,泛型类型信息在运行时可用,因此您的解析器可以确定它需要实例化什么以反序列化您的 JSON 数据。
所有这些都是您实际问题的背景信息:
我的问题是:如何在不创建 VideoResponse 的情况下将 Response 类作为参数传递给解析方法
您忽略了您正在使用的 JSON 库,但在大多数流行库中,反序列化方法都有一个覆盖版本,它接受通常称为超类型令牌的内容。超类型标记基本上只是一个类的具体扩展,类似于我上面描述的。例如,在 Jackson 中,您可以像这样反序列化 JSON:
Response<Video> response = new ObjectMapper().readValue(
jsonString, // JSON data
new TypeReference<Response<Video>>() {} // super type token, implemented by anonymous class
);
Run Code Online (Sandbox Code Playgroud)
您应该检查您的 JSON 库文档是否有类似的内容。