问题描述
使用类型ParameterizedTypeReference时只是对此行为感到好奇
这正在工作
ArrayResponse<Submission> block = webClient
.get()
.uri(newSubmissionsUri)
.attributes(clientRegistrationId(CLIENT_REGISTRATION_ID))
.retrieve()
.bodyToMono(new ParameterizedTypeReference<ArrayResponse<Submission>>() {
})
.block();
但这不起作用:
ArrayResponse<Submission> block2 = webClient
.get()
.uri(newSubmissionsUri)
.attributes(clientRegistrationId(CLIENT_REGISTRATION_ID))
.retrieve()
.bodyToMono(arrayResponse(Submission.class))
.block();
private <T> ParameterizedTypeReference<ArrayResponse<T>> arrayResponse(Class<T> clz) {
return new ParameterizedTypeReference<ArrayResponse<T>>() {
};
}
没有编译错误。但是在运行时,调试时我看到的是LinkedHashMap,而不是Submission。
也尝试过:
ArrayResponse<Submission> block2 = webClient
.get()
.uri(newSubmissionsUri)
.attributes(clientRegistrationId(CLIENT_REGISTRATION_ID))
.retrieve()
.bodyToMono(this.<Submission>arrayResponse())
.block();
private <T> ParameterizedTypeReference<ArrayResponse<T>> arrayResponse() {
return new ParameterizedTypeReference<ArrayResponse<T>>() {
};
}
但再次看到LinkedHashMap
解决方法
就像Java中的泛型一样,答案通常与类型擦除有关。
由于删除操作,您不仅可以从类本身获取泛型类型信息,还可以从父类中获取它。这就是为什么Spring和Jackson必须依靠Class.getGenericSuperclass()
来获取有关您的泛型类型的信息的原因。当你做
new ParameterizedTypeReference<ArrayResponse<Submission>>() {}
您正在创建扩展ParameterizedTypeReference<ArrayResponse<Submission>>
的新子类,Spring可以使用它来从其getGenericSuperclass
获取类型参数。但是,请注意一件事:类型在编译时是已知的,并且不能更改。现在,它确实是课程的一部分。
另一方面,当您尝试做
private <T> ParameterizedTypeReference<ArrayResponse<T>> arrayResponse() {
return new ParameterizedTypeReference<ArrayResponse<T>>() {};
}
编译器并没有真正用类型代替T
,因为该方法可能在任何位置和任何类型都已被调用。现在,这个T
也成为ParameterizedTypeReference
子类的一部分。
如果调用此方法(因此,将实际类型提供给ParameterizedTypeReference),则getGenericSuperclass
的结果仍将包含ArrayResponse<T>
,其中T
是java.lang.reflect.TypeVariable
的实例