处理 JSONArray 转 String 乱码“$ref“ -> “$[1][3]“的问题;

对 JSONArray 对象数组处理出现乱码**“$ref” -> “$[1][3]”**的问题

JSON 数组转 String 乱码 “ r e f " − > " ref"->" ref">"[1][3]”;

这个问题是我在将 JSONArray 做循环处理转字符串的过程中遇到的,一开始以为是 Integer 类型数据处理不对,一直在纠结是不是转义的问题,事实证明完全错误。

根本原因是:

​ 在 Java 中对像 Integer, Boolean, Byte, Character, Short 和 Long 这类简单类型的对象都是不可变的,这意味着一旦创建了它们的值就不能更改。因此,如果一个 JSONArray 中的两个对象引用了相同的 Integer 值,它们实际上引用的是内存中的相同对象。


“$ref” -> “$[1][3]” 实际是 JSON 指针语法。$ref 是一个 JSON 指针引用,可用于引用 JSON 文档中的另一个位置 的数据。

用代码来讲:

“$[1][3]” 在以下这个数组中表示为数字 7

[
  [0, 1, 2, 3],
  [4, 5, 6, 7]
]

JSON 指针语法提供了这一种方法来引用 JSON 文档的特定部分,这在各种上下文中都很有用,但是有时也会为我们平添许多烦恼。

问题描述:

我在对 JSONArray 做循环处理的时候,将获取的对象转换成 json 字符串后,字符串中包括 “$ref” -> “$[1][3]” 符号,造成解析异常;

示例代码如下:

List<List> lists = new ArrayList<>();
        jsonArray.forEach(item -> {
            List innerList = JSON.parseObject(String.valueOf(item), List.class);
            lists.add(innerList);
        });

一般情况下,这种 for-Each 是不会出现循环引用的问题的,但是 这里的 jsonArray 中有多个重复的 Integer 类型数据(我们已整数 1 为例),在进行第二次引用整数 1 做转字符串处理时,这里的 1 就变成了 JSON 指针引用的数据了,记录的是第一次出现 1 的位置;

解决方案:

这里为了展示直观选择了最笨重的方法:把整个 JSONArray 循环重新赋值后又做处理;

for (int i = 1; i < jsonArray.size(); i++) {
            JSONArray innerArray = jsonArray.getJSONArray(i);
            for (int j = 0; j < innerArray.size(); j++) {
                Object value = innerArray.get(j);
                if (value != null) {
                    String strValue = value.toString(); // 将任意类型的对象转换成字符串
                    innerArray.set(j, strValue);
                }
            }
        }

Object value = innerArray.get(j); 将 JSONArray 中每一个对象重新赋值,成 Object 类型;

这么做的原因是: 在 Java 中,所有非基本类型都是对象,包括数组、集合和自定义的类。对于基本类型 (例如,int, double, boolean),将一个变量的值赋给另一个变量时,将创建该值的新副本,并且这两个变量指向不同的内存位置。因此后续用 新赋值的 value 做其他处理时就不会再出现循环引用的问题了。

总结:

​ 当创建某个类型的对象时,内存中会创建该类型的新实例,并获得对该实例的引用,这是指向该对象的内存地址。对于可变的对象,例如集合或自定义的类,则可以有多个引用指向内存中的同一个对象。当通过一个引用修改对象时,更改将通过对同一对象的所有其他引用可见。如果你不小心,这可能会导致意想不到的结果。

多比比一句:

对付循环引用我们还可以通过添加序列化配置属性来关闭 FastJson 的引用检测:SerializerFeature.DisableCircularReferenceDetect;

​ 示例:取消FastJson的循环引用的检查;

 	Map map = new HashMap<>();
    List<Map> list = new ArrayList();

	map.put(1,1);
	list.add(map);
    list.add(map);
    
    System.out.println(list);
    System.out.println(JSON.toJSONString(list));
    System.out.println(JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect));


// 输出结果 :
/**
	[{1=1},{1=1}]
	[{1:1},{ "$ref" :"$[0]"}]
	[{1:1},{1:1}]
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值