问题总结:Map存入的数据丢失类型任意

发现问题:Map存入的数据丢失类型

经常会使用 Map<String,Object> 来用于存储键值对的数据,由于我们使用 Object 类型来接收数字,但是有些时候会出现map并不知道我们传入的是 Long 还是 Integer 。也就是出现数据类型丢失的问题

接下来尝试复现bug:

  1. 准备一个Map<String,Object> ,并将Long对象存入
  2. 取出该Long对象,并用instance of 判断该对象类型
    • 经过测试发现,正常的存取并不会出现该问题是正常的情况
  3. 尝试使用JSON将map序列化,转换后进行测试
    • 测试发现,BUG成功复现了,数据类型丢失了,Long类型被降级为INT

测试的Demo代码如下:

package com.test;

import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;

public class TestMain {
    
    

    public static void main(String[] args) {
    
    
        Map<String , Object> map = new HashMap<>();
        Long dataLong = 123456L;
        map.put("test",dataLong);
        System.out.println(JSON.toJSONString(map));
        Object test = map.get("test");
        System.out.println("测试一下正常使用map,是否会导致存入了Long类型丢失转换为int:");
        System.out.println(test instanceof Integer);

        // ========


        Object mapp = JSON.parse(JSON.toJSONString(map));
        Map<String , Object> objectMap = (Map<String , Object>) mapp;
        System.out.println(objectMap.toString());
        Object objectTest = objectMap.get("test");
        System.out.println("序列化存储map,是否会导致存入了Long类型丢失转换为int:");
        System.out.println(objectTest instanceof Integer);

    }
}

输出结果如下:

image-20230223214504915

问题分析

不难发现,两次的map其实对应的JSON字符串样式的一直的,但是在从字符串转换为map时丢失了数据类型。

在进行转换时, Map 会根据我们传入的数值的大小来判断。也就是说如果你传入的数值的大小是在Integer.MIN_VALUE、 Integer.MAX_VALUE 之间,Map 就认为是 Integer 类型,如果超过了这个范围就认为是 Long 类型。

在实际开发中,还挺经常遇到这种情况的,开发初期理所当然的当成int类型处理和转换,会随着数据位数的增加在中后期就报错,到时候属于是隐性BUG了。

要解决也很简单,需要我们对数据类型的转换熟悉再熟悉。

问题解决

解决的思路很简单,就是确保无论map中提取到的对象是int还是long或其他,都要统一转换为我们想要的long类型,在做处理的时候就是**将这个对象也先序列化,再转换,**这样就可以确保数据类型不会丢失,达到预期。

// 不直接强转先用 Object 接收
Object number = map.get("number");
// 下面两种二选一
Long longNumber = Long.valueOf(number.toString());
Long longNumber = Long.valueOf(String.valueOf(number));

思考:数据类型转换

顺便整理复习一下知识点

1. 包装类型不能直接强转

// 强转会报如下错误
// class java.lang.Integer cannot be cast to class java.lang.Long 
Integer number = 10;
// 这样的强转是不对的
Long number2 = (Long)number;

2. 正确的转换方式

基本数据类型之间的转换
// int 转 long
int a = 10;
long b = (long)a;
// long 转 int
long a = 10L;
int b = (int)a;
包装类型之间的转换
Integer a = 10;
Long b = a.longValue();
// Long 转 Integer
Long a = 10L;
Integer b = a.intValue();
// 或者
Long a = 10L;
Integer b = Math.toIntExact(a);

参考博客:原博写的不错

猜你喜欢

转载自blog.csdn.net/Xcong_Zhu/article/details/129191179