使用Jackson反序列化值为List的Map<Long, List<Long>>时编译报错求助
解决Jackson反序列化Map<Long, List>的编译错误
尝试用Jackson的com.fasterxml.jackson.databind.ObjectMapper反序列化Map<Long, List<Long>>时出现编译错误,以下是相关代码及错误详情:
ObjectMapper初始化代码
// ObjectMapper initialization public static final ObjectMapper objectMapper = JsonMapper.builder() .addModule(new JavaTimeModule()) .addModule(new SimpleModule() .addAbstractTypeMapping(Claims.class, DefaultClaims.class) .addAbstractTypeMapping(GrantedAuthority.class, SimpleGrantedAuthority.class) ) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .addMixIn(PersonTraits.class, PersonTraitsMixIn.class) .addMixIn(SimpleGrantedAuthority.class, SimpleGrantedAuthorityMixin.class) .build();
反序列化方法
public static <K, V, T extends Map<?, ?>> Map<K, List<V>> deserializeMap(String genericObject, Class<T> mapClass, Class<K> keyClass, Class<List<V>> valueClass) throws Exception { if (genericObject == null) { return null; } try { return objectMapper.readValue(genericObject, objectMapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass)); } catch (JsonProcessingException e) { // Do something throw e; } }
JUnit测试用例
@Test public void testDeserializeMapContainingListAsValue() throws Exception { // given Map<Long, List<Long>> mapToSerialize = new HashMap<>(); List<Long> valueList = new ArrayList<>(); valueList.add(2L); mapToSerialize.put(1L, valueList); String serializedMap = SerializationUtil.serializeObject(mapToSerialize); // when final Map<Long, List<Long>> result = SerializationUtil.deserializeMap(serializedMap, HashMap.class, Long.class, List.class); // then assertNotNull(result); }
编译错误信息
调用语句:
final Map<Long, List<Long>> result = SerializationUtil.deserializeMap(serializedMap1, HashMap.class, Long.class, List.class);
错误详情:
Required type. Provided mapClass: Class<T>. Class<HashMap> keyClass: Class<K> Class<Long> valueClass: Class<List<V>>. Class<List> reason: Incompatible equality constraint: List<V> and List
问题原因
Java泛型存在类型擦除机制,运行时List<Long>和List的Class对象是同一个,无法直接传递Class<List<V>>类型的参数。你传入的List.class实际是Class<List>,和方法定义的Class<List<V>>不匹配,导致编译错误。
解决方案
修改反序列化方法,将参数从Class<List<V>> valueClass改为Class<V> valueElementType,然后在方法内部构造List<V>的类型:
public static <K, V, T extends Map<?, ?>> Map<K, List<V>> deserializeMap(String genericObject, Class<T> mapClass, Class<K> keyClass, Class<V> valueElementType) throws Exception { if (genericObject == null) { return null; } try { // 构造List<V>的类型 Type listType = objectMapper.getTypeFactory().constructCollectionType(List.class, valueElementType); // 构造Map<K, List<V>>的类型 JavaType mapType = objectMapper.getTypeFactory().constructMapType(mapClass, keyClass, listType); return objectMapper.readValue(genericObject, mapType); } catch (JsonProcessingException e) { // Do something throw e; } }
然后修改测试用例的调用,传递Long.class作为valueElementType:
final Map<Long, List<Long>> result = SerializationUtil.deserializeMap(serializedMap, HashMap.class, Long.class, Long.class);
这样就能正确编译并完成反序列化了。
内容的提问来源于stack exchange,提问作者Sandeep Barnabas
相关产品推荐
相关产品推荐

