记录一次java.lang.ClassCastException的java类型转换异常解决方案-附最终解决方案

自己的项目中,有个定时任务的模块,里面需要将返回的对象强转为某个实体类JobModel,可是在转换的过程中,却报出了java.lang.ClassCastException: com.jy.admin.server.model.JobModel cannot be cast to com.jy.admin.server.model.JobModel

at com.jy.admin.server.service.impl.JobServiceImpl.doJob(JobServiceImpl.java:103)这样的异常,

找到对应的那行代码

 
JobModel jobModel=(JobModel)jobDataMap.get(JOB_DATA_KEY);

就是这行代码出现了强转的错误.

期间也将该对象打印出来,发现确实是JobModel对象,debug的时候,那个对象里面存的数据也是正确的,初步怀疑是JobModel的serialVersionUID发生了改变,但后面发现并不是这个原因;

问题产生了就要解决,抓耳挠晒下,想到了一个解决办法,既然数据存在这个对象中没错,那就曲线救国一下,先将该对象转换成json,然后再转换回来,问题完美解决,代码如下,原因未知

 

Object temp = jobDataMap.get(JOB_DATA_KEY);
JobModel jobModel=new JobModel();
System.out.println(temp);
if (temp instanceof JobModel){
   jobModel= (JobModel) temp;
}else {
   String string = JSON.toJSON(temp).toString();
   System.out.println(string);
   jobModel = JSON.parseObject(string, JobModel.class);
}

最终解决方案:

麦奇: 楼主,原因是因为你们的项目中应该是采用了热部署,devtools,因为累加载器的不同所以会导致类型转换失败(5个月前#4楼)

 

琳达chu: 楼主我碰到的问题和你一模一样,是spring的devtools引起的,你把下面的依赖去掉应该就可以了

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-devtools</artifactId>

    <scope>runtime</scope>

</dependency>

我的微信公众号:架构真经(关注领取免费资源)

### 问题解析 `java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String` 是由于尝试将 `HashMap` 对象强制转换为 `String` 类型所引发的运行时异常。这种错误通常发生在数据类型不匹配的情况下,尤其是在处理集合框架(如 List 或 Set)时未正确指定泛型或误用了对象类型的场景下。 以下是针对该问题的具体解决方案--- ### 解决方案 #### 方法一:确认并修正泛型定义 如果程序中使用了未经泛型限定的集合类(如 `List`),可能导致存储的数据类型与预期不符。例如,当一个 `List<HashMap>` 被当作 `List<String>` 使用时,就会触发此异常[^2]。 确保在声明集合变量时明确定义其泛型类型,例如: ```java // 正确方式:显式指定泛型类型 List<Map<String, Object>> list = new ArrayList<>(); ``` 这样可以避免因类型推断错误而导致的隐式转换问题。 --- #### 方法二:安全地访问集合元素 在遍历集合前,应先验证其中的实际数据类型是否符合预期。可以通过 `instanceof` 关键字进行类型检查后再执行强转操作。例如: ```java Object obj = list.get(i); if (obj instanceof Map) { Map<String, Object> map = (Map<String, Object>) obj; // 安全地访问 Map 中的内容 } else { throw new IllegalArgumentException("Unexpected type found in the list."); } ``` 上述代码片段能够有效防止非法类型转换的发生[^5]。 --- #### 方法三:序列化/反序列化替代直接转换 对于复杂对象(如 `HashMap`),建议采用 JSON 序列化工具将其转化为字符串形式再进一步处理。这种方式不仅规避了潜在的类型冲突风险,还增强了代码的可读性和维护性[^4]。示例实现如下: ```java import com.google.gson.Gson; Gson gson = new Gson(); for (int i = 0; i < list.size(); i++) { String jsonString = gson.toJson(list.get(i)); System.out.println(jsonString); try { JSONObject jsonObject = new JSONObject(jsonString); System.out.println(jsonObject.getString("keyName")); } catch (JSONException e) { e.printStackTrace(); } } ``` --- #### 方法四:调整 Redis 数据存取逻辑 如果是基于 Redis 的应用场景,则需注意哈希表结构内的值类型一致性。若某些字段可能包含不同基础类型(如整数、布尔值等),则统一将其映射至字符串表示更为稳妥[^3]。具体做法见以下代码段: ```java import org.springframework.beans.BeanUtils; import cn.hutool.core.bean.copier.CopyOptions; import java.util.Map; public static void main(String[] args) { UserDTO userDTO = ... ; // 初始化 DTO 实体 // 将实体属性复制到 Map 并自动完成 toString 处理 Map<String, Object> userMap = BeanUtils.beanToMap( userDTO, new HashMap<>(), CopyOptions.create() .setIgnoreNullValue(true) .setFieldValueEditor((field, value) -> value != null ? value.toString() : "") ); redisTemplate.opsForHash().putAll("loginUser:" + userId, userMap); } ``` --- ### 总结 以上四种策略分别从根源控制、运行防护以及实际应用层面提供了应对措施。开发者可根据具体情况选用最合适的手段解决问题。 --- ###
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十步杀一人_千里不留行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值