Just curious about this behavior when using Type ParameterizedTypeReference
This is working
ArrayResponse<Submission> block = webClient
.get()
.uri(newSubmissionsUri)
.attributes(clientRegistrationId(CLIENT_REGISTRATION_ID))
.retrieve()
.bodyToMono(new ParameterizedTypeReference<ArrayResponse<Submission>>() {
})
.block();
but this is not working:
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>>() {
};
}
There are no compilation errors. But at runtime, instead of Submission, I'm seeing LinkedHashMap when I debug.
Also tried:
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>>() {
};
}
but again seeing LinkedHashMap
As very often with generics in java, the answer is related to the type erasure.
Because of the erasure, you can't just get the generic type information from the class itself, but it's possible to get it from a parent class. That's why Spring and Jackson have to rely on
Class.getGenericSuperclass()
to get the information about your generic type. When you doyou're creating a new subclass that extends
ParameterizedTypeReference<ArrayResponse<Submission>>
, and Spring can use it to get the type parameter from itsgetGenericSuperclass
. However, note an important thing: the type is known at compile time, and can't change. It's now really a part of the class.On the other hand, when you try to do
the compiler doesn't really substitute
T
with the type, because the method might have been called in any place and with any type. ThisT
now also becomes a part of theParameterizedTypeReference
subclass.If you call this method (thus, providing the actual type to ParameterizedTypeReference) the result of
getGenericSuperclass
will still containArrayResponse<T>
, withT
being an instance ofjava.lang.reflect.TypeVariable
.