当前位置:网站首页>看我在Map<String, String>集合中,存入Integer类型数据
看我在Map<String, String>集合中,存入Integer类型数据
2022-06-26 09:37:00 【默辨】
一、前情提要
前几天测试给我提了一个缺陷,提示类型转化报错,可是我怎么看对应的代码都想不明白问题在哪里
1、缺陷背景
将模型大致抽象一下,就是其他同事将前台的数据放入到一个map中,然后再把这个map转为json字符串传给后台,紧接着再把这个json字符串反序列化为一个map对象,最后把这个map对象传递给我。
2、报错提示如下:
光看报错提示,其实还是很开心的,这明显是一个类型转化异常,那必然是我将一个Integer类型的数字转化为一个String类型的字符串导致的,继续往下看

3、代码报错的位置
定位到报错的位置是下面的方法,然后我陷入了沉思,String转Integer?你这是哪门子的类型转化异常?我这不是两个String?

4、该方法只是一个简单的判空方法

二、寻找问题
1、捞日志看接收参数
心里窃喜,还好我把接收的参数打印在了日志里面。结果发现我在打日志的时候是直接传的map,并没有对其进行自定义的序列化,以至于我无法看到数据对应的类型(后文会说明,这个数据类型很重要),下次自己得记住要序列化

2、观察前台传给后台的参数
无奈,我只能前台看对应的参数情况,最终在前台的参数里面找到了它。发现一个参数不像是字符串

3、再次执行判断方法
然后我用数字类型的参数去执行StringUtils.isNotBlank()方法,只能说这个错误对味了。
但是新问题来了:
- 如果直接是数字编译通不过呀!
- 就算是Object类型的参数,我这里还需要强转,可是我的代码没有强转呀!
- 还有就是我报错的方法的参数泛型为Map<String,String>,泛型限定为String类后都不能接收Integer类型的参数呀!真的吗?

4、于是在阅读了同事的代码之后,再次定位问题
同事的工作其实就是把前台给的json字符串,反序列化为一个Map<String,String>的集合中。那么问题只能是在这个反序列化了,明明传进去的时候都还有数字,怎么出来就没有数字了?
三、验证问题
1、自己反序列化测试
模拟全过程代码
public class Map泛型兼容 {
public static void main(String[] args) {
// 模拟前台的传给后台的数据
Map<String, Object> map = new HashMap<>();
map.put("key1", 1);
map.put("key2", "a");
String jsonStr = "";
jsonStr = JSON.toJSONString(map);
// 传给后台的json字符串
System.out.println(jsonStr);
// 对字符串进行反序列化
Map<String, String> params = JSON.parseObject(jsonStr, HashMap.class);
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() instanceof String) {
} else {
System.out.println("不是字符串类型");
}
System.out.println(entry.getValue());
}
}
}

我们惊奇的发现,居然不报错,他居然不报错,他居然不报错,Integer的转化为String居然没问题,并且最终拿到数据的时候也还是Integer类型,我直接好家伙。
然后我就联想了一下json反序列化是通过反射完成的。
2、反射再验证
它居然还真可以,我使用反射向Map<String,String>的对象中添加数据,然后遍历该map对象,但是却发现其value是一个Integer类型。
那么一切就说的通了

验证代码:
public class TestReflect {
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
Method put = map.getClass().getMethod("put", Object.class, Object.class);
put.invoke(map, "key1", 1);
put.invoke(map, "key2", "value2");
System.out.println(JSON.toJSON(map));
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getValue() instanceof String) {
} else {
System.out.println("该key是其他类型:" + entry.getValue().getClass());
}
}
}
}
3、结论
最终的结论就是,同事在把前台的所有参数传到后台的时候,里面包含了一个value为Integer类型的数据,那类比就是放到了一个Map<String,Object>的map集合中,在对该map进行序列化后,就变成了一个普通的json字符串。
问题的关键就在于反序列这个位置,在对该json字符串反序列化的时候,就出现了问题。但是这个属于运行时异常了。因为我们的json字符串里面含有Integer类型的参数,但是反序列化的对象却是一个String类型,根据前文的演示,在利用反射进行赋值的时候,并不会报错,以至于一切风平浪静。
但当在我们在使用对应参数的时候,问题就来了,因为我们只认反序列化回的String类型的map,但是实际拿到的却是Integer,以至于引发了后续的错误。
那我们应该如何使用呢?
在我看来我们如果无法明确参数是否可能存在多种类型,可以使用Object类型的map接收反序列出来的集合数据,在获取对应参数的时候也不要使用强转的形式,而是使用更加友好的String.valueOf获取对应的内容(其底层就是调用包装类型的toString方法)

边栏推荐
- 【LeetCode】59. 螺旋矩阵 II
- 【LeetCode】59. Spiral matrix II
- The basis of C language grammar -- function nesting, Fibonacci sum of recursive applet and factorial
- Selection of webrtc video codec type VP8 H264 or other? (openh264 encoding, ffmpeg decoding)
- Threading model in webrtc native
- 调用api接口生成不同颜色的微信小程序二维码
- MySQL第七次作业-更新数据
- SSM项目小例子,SSM整合图文详细教程
- jar版本冲突问题解决
- Problems encountered in the application and development of Hongmeng and some roast
猜你喜欢

904. 水果成篮

The IE mode tab of Microsoft edge browser is stuck, which has been fixed by rolling back the update

Standard implementation of streaming layout: a guide to flexboxlayout

Reshape a two-dimensional array with 3 rows and 3 columns to find the sum of the diagonals

MySQL job 11 - application de la vue

Develop current learning objectives and methods

MySQL第七次作业-更新数据

Appium自动化测试基础 — 移动端测试环境搭建(二)

MySQL第十次作业-视图

全渠道、多场景、跨平台,App如何借助数据分析渠道流量
随机推荐
二叉树常见面试题
Searchview click failure
Global and Chinese markets in hair conditioner 2022-2028: Research Report on technology, participants, trends, market size and share
Standard implementation of streaming layout: a guide to flexboxlayout
MySQL第十三次作业-事务管理
How to start the learning journey of webrtc native cross platform development?
瑞萨电子面向物联网应用推出完整的智能传感器解决方案
Extracting public fragments from thymeleaf
904. fruit baskets
Call API interface to generate QR code of wechat applet with different colors
Automated testing -- Introduction and example of pytest framework
首批12家企业入驻!广州首个集中展销老字号产品专柜开张
Recyclerview implements flow layout (LinearLayout with line wrap) (flexboxlayoutmanager)
Crawler related articles collection: pyppeter, burpsuite
創建對象的時候堆內存的分配
【深度优先搜索】312.戳气球
Blog post index summary --c #
String constant pool, class constant pool, and runtime constant pool
cmake / set 命令
LSP 是什么