Fastjson JSONObject/JSONArray new Type(Object)深复制失败的原因

Fastjson JSONObject/JSONArray new Type(Object)深复制失败的原因

目录

Fastjson JSONObject/JSONArray new Type(Object)深复制失败的原因

1,new JSONObject (Object);

代码:

看源码:

调试:

2,new JSONArray(Object);

代码:

源码:

调试:

3,处理:

总结:


由fastjson 的 JSONObject深复制 和 JSONArray深复制 各自第一个例子中使用new JSONObject(Object) 和 new JSONArray(Object)进行深复制失败了,其中的原因呢?

 

1,new JSONObject (Object);

代码:

public static void main(String[] args){
    testNewJson();
}

public static void testNewJson(){
    System.out.println("====== new JSONObject fail =======");
    JSONObject one = new JSONObject();
    one.put("one","fish");
    JSONObject two = new JSONObject(one);
    System.out.println("init: one: "+ one.toString());
    System.out.println("init: two: "+ two.toString());
    two.put("one","grass");
    System.out.println("change: one: "+ one.toString());
    System.out.println("change: two: "+ two.toString());
    System.out.println("内存地址: one: "+ System.identityHashCode(one));
    System.out.println("内存地址: two: "+ System.identityHashCode(two));
    System.out.println();
}

 

结果:

====== new JSONObject fail =======

init: one: {"one":"fish"}

init: two: {"one":"fish"}

change: one: {"one":"grass"}

change: two: {"one":"grass"}

内存地址: one: 544724190

内存地址: two: 1972439101

new JSONObject(one) 这种方式失败了。

内容地址也不同,应该会一样才对,然而并没有?为什么呢?

 

看源码:

private final Map<String, Object> map;

public JSONObject(Map<String, Object> map) {
    if (map == null) {
        throw new IllegalArgumentException("map is null.");
    } else {
        this.map = map;
    }
}


public Object put(String key, Object value) {
    return this.map.put(key, value);
}

 

调试:

JSONObject one = new JSONObject();
    one.put("one","fish");

JSONObject two = new JSONObject(one);

two.put("one","grass");

两个内容还是指向同一个map内容,变成了复制引用,two赋值的时候,也会改变one的内容。

 

2,new JSONArray(Object);

代码:

public static void main(String[] args){
    testNewJsonArr();
}

public static void testNewJsonArr(){
    System.out.println("====== new JSONArray fail =======");
    JSONArray oneArr = new JSONArray();
    JSONObject one = new JSONObject();
    one.put("one","fish");
    oneArr.add(one);
    JSONArray twoArr = new JSONArray(oneArr);
    System.out.println("init: oneArr: "+ oneArr.toString());
    System.out.println("init: twoArr: "+ twoArr.toString());
    System.out.println("====== add bird =======");
    JSONObject two = new JSONObject();
    two.put("two","bird");
    twoArr.add(two);
    System.out.println("change: oneArr: "+ oneArr.toString());
    System.out.println("change: twoArr: "+ twoArr.toString());
    System.out.println("内存地址: oneArr: "+ System.identityHashCode(oneArr));
    System.out.println("内存地址: twoArr: "+ System.identityHashCode(twoArr));
    System.out.println("====== fail =======");
}

 

结果:

====== new JSONArray fail =======

init: oneArr: [{"one":"fish"}]

init: twoArr: [{"one":"fish"}]

====== add bird =======

change: oneArr: [{"one":"fish"},{"two":"bird"}]

change: twoArr: [{"one":"fish"},{"two":"bird"}]

内存地址: oneArr: 544724190

内存地址: twoArr: 277630005

====== fail =======

New JSONArray的方式失败,为什么失败呢?

看内存的地址是不同的,但结果还是变成了复制引用。

 

源码:

private final List<Object> list;

public JSONArray(List<Object> list) {
    if (list == null) {
        throw new IllegalArgumentException("list is null.");
    } else {
        this.list = list;
    }
}



public boolean add(Object e) {
    return this.list.add(e);
}

 

调试:

oneArr.add(one);

twoArr.add(two);

调式的时候,发现两个内容还是指向同一个list内容,变成了复制引用,twoArr添加内容的时候,也会改变oneArr的内容。

 

3,处理:

  了解了fastjson里面的JSONObject和JSONArray,不能使用new JSONObject(Object),new JSONArray(Object)进行深度复制的原因。那有办法进行改写处理吗? 由上面的源码可以看到

  private final Map<String, Object> map;

    private final List<Object> list;

属性里面都加了final字段,由final关键字的特性:“如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改”,目前看似乎是无解的,只能另寻他路,比如使用putAll或是addAll的方式进行处理了。

 

总结:

   在使用fastjon 的JSONObject和JSONArray进行深度复制的时候,我以为可以跟map和list的方式一样的,然而却不相同,调试源码的时候,才发现原因。对于有些现象,自己搞不懂的,要耐下心来,好好去看下源码,调式下,也许会发现问题。再不行就问问大佬。学习嘛,常说要有“打破砂锅问到底”的精神。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值