Java中含List字段的对象转Map报错,求解决方案
解决Java对象转Map含List字段的序列化错误
你遇到的错误提示翻译为:无法从数组值(标记为JsonToken.START_ARRAY)反序列化java.lang.String类型的值
你的代码示例:
static class User { private String name; private List<Integer> ages; } @Test void t3() { final ObjectMapper objectMapper = new ObjectMapper(); final User kim = new User("kim", Arrays.asList(1, 2)); objectMapper.convertValue(kim, new TypeReference<Map<String, List<Object>>>() {}); // 报错 // objectMapper.convertValue(kim, new TypeReference<Map<String, Object>>() {}); // 也不生效 }
问题原因
- 第一种写法
Map<String, List<Object>>:User类里的name是String类型,你强制要求所有Map值都是List类型,Jackson尝试把String转成List,自然触发类型不匹配错误。 - 第二种写法
Map<String, Object>本身逻辑正确,但不生效是因为你的User类缺少Jackson序列化所需的必要结构:无参构造函数、字段的getter方法,或者字段访问权限不足。
解决办法
1. 补全User类的序列化必要结构
Jackson默认需要类有无参构造函数,并且能通过getter方法访问字段值,修改后的User类如下:
static class User { private String name; private List<Integer> ages; // 必须添加无参构造 public User() {} // 带参构造保留 public User(String name, List<Integer> ages) { this.name = name; this.ages = ages; } // 添加getter方法 public String getName() { return name; } public List<Integer> getAges() { return ages; } }
2. 使用正确的TypeReference
用Map<String, Object>作为目标类型,它能兼容String和List两种不同类型的字段:
@Test void t3() { final ObjectMapper objectMapper = new ObjectMapper(); final User kim = new User("kim", Arrays.asList(1, 2)); // 正确转换 Map<String, Object> userMap = objectMapper.convertValue(kim, new TypeReference<Map<String, Object>>() {}); // 验证结果 System.out.println(userMap.get("name")); // 输出 kim System.out.println(userMap.get("ages")); // 输出 [1, 2] }
简化方案:使用Lombok
如果项目中引入了Lombok,可以用@Data注解自动生成无参构造、getter/setter等代码,简化User类:
import lombok.Data; @Data static class User { private String name; private List<Integer> ages; // 带参构造可保留,或用@AllArgsConstructor注解生成 public User(String name, List<Integer> ages) { this.name = name; this.ages = ages; } }
内容的提问来源于stack exchange,提问作者JavaMe
相关产品推荐
相关产品推荐

