【异常】类型转换异常:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXX

背景

有一个实体类 User:

public class User {
    private String id;
    private String name;
    private String age;
}

后端调用其他服务的接口,得到的响应 response 是这样的:

{
    "success": true,
    "data": [
        {"id": 1, "name": "张三", "age": "16"},
        {"id": 2, "name": "李四", "age": "17"},
        {"id": 3, "name": "王五", "age": "18"}
    ],
    "message": null,
    "errorCode": 200
}

现在需要从响应里解析出 data 里的 idname 字段。写法如下:

List<User> userList = (List<User>) response.getData();
Map<String, String> map = userList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e.getName()));

结果报错了!报错信息:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to User

原因

通过打断点调试,可以发现得到的 List<User> 里的元素类型并不是 User 实体类,而是 LinkedHashMap
在这里插入图片描述
为什么我们已经用 List<User> 来声明了,结果得到的 List 里的元素类型却是 LinkedHashMap 呢?

主要是因为我们要用的对象没有在本地形成类型强引用,JVM没办法将当前对象关联到字节码文件。

所以,只需要将这个对象先转为JSON字符串,然后通过JSON工具转为对象就行。

解决方法

第一种做法:TypeReference

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
List<User> userList= mapper.convertValue(response.getData(), new TypeReference<List<User>>(){});
Map<String, String> map = userList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e.getName()));

如果 data 里的数据没有对应的实体类,也可以这样:

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
List<JSONObject> userList= mapper.convertValue(response.getData(), new TypeReference<List<JSONObject>>(){});
Map<String, String> map = userList.stream().collect(Collectors.toMap(e -> e.getString("id"), e -> e.getString("name")));

第二种做法:JavaType

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
// 排除json字符串中实体类没有的字段
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
JavaType javaType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, JSONObject.class);
List<JSONObject> userList = mapper.readValue(response.getData(), javaType);

需要用到的工具包的依赖:

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.38</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
			<version>1.5.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
			<version>1.5.1.RELEASE</version>
		</dependency>
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值