微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当使用泛型作为函数调用时,ParameterizedTypeReference返回LinkedHashMap

如何解决当使用泛型作为函数调用时,ParameterizedTypeReference返回LinkedHashMap

使用类型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>,其中Tjava.lang.reflect.TypeVariable的实例

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。