失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Map<String Object>接收参数 Long类型降级为Integer 报类型转换异常

Map<String Object>接收参数 Long类型降级为Integer 报类型转换异常

时间:2020-03-16 01:43:25

相关推荐

Map<String Object>接收参数 Long类型降级为Integer 报类型转换异常

前言

今天看群里小伙伴问了一个非常有意思的问题:

使用 Map<String,Object> 对象接收前端传递的参数,在后端取参时,因为接口文档中明确该字段类型为 Long ,所以对接收的参数进行了强转,即(Long)参数,但是却发生了类型转换异常,报错信息如下:

class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap')

发现好几个小伙伴也有疑惑,干脆直接码一篇文章解答一下,希望对有此疑惑的小伙伴有所帮助。

Long 类型降级

我们先通过测试数据、测试方法来还原一下问题。

测试json数据如下:

{"user_name": "niceyoo","age": -24,"money": 2147483646}

测试test方法如下:

@PostMapping("/test")@ResponseBodypublic void test(@RequestBody Map<String,Object> params) {String userName = (String) params.get("user_name");Integer age = (Integer) params.get("age");Long money = (Long) params.get("money");System.out.println(String.format("user_name=%s,age=%s,money=%s",userName,age,money));}

如上传递了三个参数,即用户名、年龄、金额这三个字段,如下是调用情况:

通过截图下方断点参数可以看到接收的 age 、money 都是 Interger 类型,而代码中 money 使用 Long 强转的话会报java.lang.Long cannot be cast to java.lang.Integer异常,至此问题就还原出来了。

不懂就问:为什么接收的 money 是 Integer 类型,强转后会报错?

首先我们先来看为什么接收的 money 是 Integer 类型。

使用 Map<String,Object> 接收的 Long 数值如果处于 「Integer.MIN_VALUE ~ Integer.MAX_VALUE」 是会自动转换成 Integer 的。

不光是接收,同样直接使用 Map<String,Object> 存入数据符合这个范围,仍然也会被认为存入的是 Integer 类型,我们可以把它看做一种潜在的优化,毕竟 Long 类型使用的字节数要大于 Integer 。

Integer.MAX_VALUE,Integer 类型的最大值,

Integer.MIN_VALUE,Integer 类型的最小值,

这两个值可以直接通过 sout 打印查看:

System.out.println(Integer.MAX_VALUE): 2147483647System.out.println(Integer.MIN_VALUE): -2147483648

我们来验证一下,将 money 的值改成大于 Integer.MAX_VALUE:

同样的,如果传递的值小于 -2147483648,那么同样接收的类型为 Long,大家可以验证一下。

为什么强转后会报错?

强转的一些条件:

低阶转高阶可以直接转;高阶转低阶需要强制转换,否则报错;强转 null 值报错;包装类型数据不支持直接跨类型强转;

其实报错的原因就是这最后一条,包装类型是不支持直接跨类型强转的,比如,你可以使用 Integer 跟 int 的直接转换,但是你不能将 Integer 直接强转成 Long 类型,或者 Long 类型强转 Integer ,这样都是报错的。

如果不能确定接收的对象是 Long 还是 Integer 怎么办?

既然知道不能强转了,但是如果不知道接收的对象是什么类型怎么办?

因为这种情况下,你不知道接收的对象到底是超过 Integer 这个范围还是没有超过。

第一种解决方法就是对接收的对象进行类型判断。

主要就是使用关键字 —instanceof

如图所示,我们可以先用 Object 接收一下对象,然后对其通过instanceof关键字进行类型判断,如果是 Integer 类型,则先 .toString(),然后再使用 Long.parseLong() 进行转换,如果本身就是 Long,则直接进行强转,同理,接收 Integer 类型也一样,无非就是换用 Integer.parseInteger().

第二种就是直接使用实体接收,使用实体接收就不会存在此问题了。

博客园持续更新,欢迎关注,希望这篇文章对你有所帮助。

博客园:/niceyoo

如果觉得《Map<String Object>接收参数 Long类型降级为Integer 报类型转换异常》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。