记一次java.lang.ClassCastException的java类型转换异常解决方案

一、问题描述

在系统中应用了spring的@Cacheable注解功能,首次请求方法没问题,但在二次加载中,会抛出类转换异常,根本原因是:同一个类的加载类不同,既:applicationClassLoader 和 RestartClassLoader。

    @Override
    @Cacheable(cacheNames = {"all_menus"})
    public List<Menu> selectAll() {
        return menuMapper.selectAll();
    }

二、 最终解决方案:

原因是因为我的项目中应该是采用了热部署,devtools,因为类加载器的不同所以会导致类型转换失败,是spring的devtools引起的,把下面的依赖去掉应该就可以了。

<dependency>
 
    <groupId>org.springframework.boot</groupId
`java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String` 是 Java 中非常常见的类型转换异常。它表示你试图将一个 `Integer` 型的对象强制转换为 `String` 型,但这是不允许的,因为它们不是兼容型。 在 **MyBatis** 框架中,这种错误通常发生在你对结果集的处理或参数传递时型不匹配,尤其是在使用 `Map`、`ResultMap`、`@MapKey`、`动态 SQL` 等功能时。 --- ## 🔍 常见 MyBatis 报错场景及示例 ### ✅ 场景一:从 `Map` 中取值时型错误 ```java Map<String, Object> result = sqlSession.selectOne("selectUser", 1); String name = (String) result.get("name"); // ❌ 如果 name 是 Integer 型就会报错 ``` #### ❌ 错误原因: - 数据库字段 `name` 实际上是 `INT` 型,而你却强制转换为 `String`。 #### ✅ 正确做法: ```java Object nameObj = result.get("name"); if (nameObj instanceof String) { String name = (String) nameObj; } else if (nameObj instanceof Integer) { String name = nameObj.toString(); // 安全转换 } ``` --- ### ✅ 场景二:MyBatis 映射文件中字段型不匹配 ```xml <resultMap id="userResultMap" type="User"> <result property="name" column="id"/> <!-- id 是 INT,name 是 String --> </resultMap> ``` #### ❌ 错误原因: - `id` 是数据库中的整型字段,被映射到 Java 的 `String` 属性上,MyBatis 自动赋值时可能会出错(取决于是否使用型处理器)。 #### ✅ 正确做法: - 修正字段映射,或使用 `TypeHandler` 处理类型转换: ```xml <resultMap id="userResultMap" type="User"> <result property="name" column="name"/> <!-- 正确字段 --> </resultMap> ``` --- ### ✅ 场景三:使用 `@MapKey` 注解时键型错误 ```java @MapKey("id") // id 是 Integer 型 Map<String, User> selectUsers(); // 键是 String,实际是 Integer ``` #### ❌ 错误原因: - `@MapKey("id")` 返回的是 `Integer`,但你定义的 Map 键是 `String`,型不匹配。 #### ✅ 正确做法: ```java @MapKey("id") Map<Integer, User> selectUsers(); // 键为 Integer ``` --- ### ✅ 场景四:动态 SQL 中参数型不匹配 ```java List<User> getUsers(@Param("id") String id); // 接口定义为 String ``` ```xml <select id="getUsers" resultType="User"> SELECT * FROM users WHERE id IN <foreach collection="id.split(',')" item="item" open="(" separator="," close=")"> #{item} </foreach> </select> ``` #### ❌ 错误原因: - `id` 实际是 `Integer`,但被传为 `String`,`split` 会失败或解析出 `Integer` 型,但你在 SQL 中使用时没有做型处理。 #### ✅ 正确做法: - 修改接口参数为 `Integer` 或 `String`,确保前后一致: ```java List<User> getUsers(@Param("id") Integer id); ``` --- ### ✅ 场景五:使用 `resultType="map"` 查询时处理不当 ```java Map<String, Object> result = sqlSession.selectOne("selectData"); String value = (String) result.get("value"); // 如果 value 是 Integer 会报错 ``` #### ✅ 正确做法: ```java Object valueObj = result.get("value"); String value = valueObj != null ? valueObj.toString() : null; ``` --- ## 🧪 常见类型转换错误汇总 | 场景 | 报错型 | 原因 | 建议解决方案 | |------|-----------|------|----------------| | 从 Map 取值错误 | `Integer -> String` | 数据库字段和 Java 属性型不匹配 | 使用 `instanceof` 判断或 `toString()` | | ResultMap 映射错误 | `Integer -> String` | 映射字段型不一致 | 检查字段映射或使用 `TypeHandler` | | @MapKey 键型错误 | `Integer -> String` | 键型不一致 | 保持 Map 键与 `@MapKey` 返回值型一致 | | 动态 SQL 参数错误 | `Integer -> String` | 参数传递型不一致 | 统一接口和 SQL 中参数型 | | 使用 Map 结果集 | `Integer -> String` | 没有做型判断 | 使用安全转换或 `toString()` | --- ## ✅ 总结建议 1. **不要直接强制类型转换**,使用 `instanceof` 判断型。 2. **确保数据库字段和 Java 属性型匹配**,或使用 `TypeHandler`。 3. **使用 `toString()` 安全转换非字符串型**。 4. **避免在 MyBatis 中混用不兼容的型**,尤其是在 Map 和动态 SQL 中。 5. **调试时打印出 Map 的 value 型**,有助于排查问题。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值