在 Java 中使用泛型时遇到的问题,,无法正确将响应数据映射为需要的数据
public <T> List<T> getOrderList(String shopId, Class<T> tClass) {// --- 省略一些中间过程----ParameterizedTypeReference<KeRuYunCommonResultVO<KPOSPageResultVO<T>>> responseType =new ParameterizedTypeReference<KeRuYunCommonResultVO<KPOSPageResultVO<T>>>() {};ResponseEntity<KeRuYunCommonResultVO<KPOSPageResultVO<T>>> resultEntity= restTemplate.exchange(uri,HttpMethod.POST,httpEntity, responseType);// --- 省略一些中间过程----return null;}
调用
List<KryKopsOrder> dataList= keRuYunServiceManager.getOrderList(KPOS,"XXXXXXXX",KryKopsOrder.class);
问题分析
代码中,使用了 ParameterizedTypeReference<KeRuYunCommonResultVO<KPOSPageResultVO>> 来指定泛型类型信息,但由于 Java 的类型擦除特性,这样仍然可能不足以让 Jackson(ObjectMapper 的底层库)正确地反序列化泛型参数 T。
解决方案:使用自定义的 ParameterizedTypeReference
通过以下步骤进一步明确类型信息,从而解决泛型类型映射问题:
- 创建一个 ParameterizedTypeReference 的子类:在实际调用时明确指定泛型类型 T。
- 使用 TypeFactory 提供准确的类型信息:确保 Jackson 能获取正确的类型信息。
// 使用 TypeFactory 创建泛型类型JavaType responseType = objectMapper.getTypeFactory().constructParametricType(KeRuYunCommonResultVO.class,objectMapper.getTypeFactory().constructParametricType(KPOSPageResultVO.class, tClass));ResponseEntity<KeRuYunCommonResultVO<KPOSPageResultVO<T>>> resultEntity = restTemplate.exchange(uri,HttpMethod.POST,httpEntity,ParameterizedTypeReference.forType(responseType));
解释
-
JavaType: 通过 ObjectMapper 的 TypeFactory 来构建一个包含泛型类型信息的 JavaType
对象。这里指定了 KeRuYunCommonResultVO 和 KPOSPageResultVO 的参数类型为 T。 -
ParameterizedTypeReference.forType(responseType): 将构建的 JavaType 转换为
ParameterizedTypeReference,从而明确指定泛型类型信息。