最近做一个功能的时候,想复制一个 JSONObject 里的所有属性,就直接使用的 new JSONObject(original),之后对新new的和老的 JSONObject 进行了一些操作,然后落库,发现落库的数据总是有问题,怪怪的。最后发现 new JSONObject(original) 出来的JSONObject和老的JSONObject是 共享 的属性。故此记录一下。
我这里使用的是 alibaba 的 com.alibaba.fastjson.JSONObject。
我们先说说什么是 深拷贝?什么是 浅拷贝?
深拷贝:深拷贝是指创建一个新的对象,并递归地复制原始对象中的所有引用类型数据结构,包括内部的对象。深拷贝后的对象与原始对象 完全独立,对其中一个对象的修改 不会影响 另一个对象。
浅拷贝:浅拷贝是指创建一个新的对象,该对象的内容是原始对象的副本。如果原始对象中包含了引用类型的数据结构(如列表、字典等),浅拷贝只会复制这些引用,而不会复制引用指向的对象本身。因此,原始对象和浅拷贝后的对象会 共享 一些内部对象的引用,修改其中一个对象的共享部分 可能会影响 另一个对象。(这个知识点,我在之前的博文里提及过了,自己用的时候也搞忘了)
浅拷贝 —— 修改新 JSONObject,原对象也会被修改:- public static void main(String[] args) { // 原始对象 JSONObject original = new JSONObject(); original.put("name", "张三"); // 原始对象中的嵌套对象 JSONObject address = new JSONObject(); address.put("city", "北京"); address.put("street", "长安街"); original.put("address", address); // 使用构造函数"拷贝" JSONObject copy = new JSONObject(original); copy.put("name", "李四"); // 修改浅拷贝后对象的嵌套内容 copy.getJSONObject("address").put("city", "上海"); System.out.println("原始对象: " + original); System.out.println("拷贝对象: " + copy); System.out.println("address是否同一个对象: " + (original.get("address") == copy.get("address"))); // 输出结果: // 原始对象: {"address":{"city":"上海","street":"长安街"},"name":"李四"} // 拷贝对象: {"address":{"city":"上海","street":"长安街"},"name":"李四"} // address是否同一个对象: true (证明是浅拷贝) }
复制代码 后来我调整了代码,使用 序列化 来实现深拷贝:- public static void main(String[] args) { // 原始对象 JSONObject original = new JSONObject(); original.put("name", "张三"); // 原始对象中的嵌套对象 JSONObject address = new JSONObject(); address.put("city", "北京"); address.put("street", "长安街"); original.put("address", address); // 深拷贝:先序列化为JSON字符串,再反序列化为新对象 String jsonStr = original.toJSONString(); JSONObject deepCopy = JSONObject.parseObject(jsonStr); deepCopy.put("name", "李四"); // 修改深拷贝后的子对象 deepCopy.getJSONObject("address").put("city", "上海"); System.out.println("原始对象: " + original); System.out.println("拷贝对象: " + deepCopy); System.out.println("address是否同一个对象: " + (original.get("address") == deepCopy.get("address"))); // 输出结果: // 原始对象: {"address":{"city":"北京","street":"长安街"},"name":"张三"} // 拷贝对象: {"address":{"city":"上海","street":"长安街"},"name":"李四"} // address是否同一个对象: false (证明是深拷贝) }
复制代码 当我们在上下文中使用JSON对象时,总是假设需要深拷贝,除非我们能明确使用浅拷贝是符合需求,跟我们想要的结果是一致的。
业精于勤荒于嬉,行成于思毁于随。-- 烟沙九洲
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |