new JSONObject(original) 是浅拷贝
作者:互联网
2026-03-26
最近做一个功能的时候,想复制一个 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对象时,总是假设需要深拷贝,除非我们能明确使用浅拷贝是符合需求,跟我们想要的结果是一致的。
业精于勤荒于嬉,行成于思毁于随。-- 烟沙九洲
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
【从0到1构建一个ClaudeAgent】并发-后台任务
MyBatis、MyBatis-Plus、JPA、MyBatisGX 写法比较:同一个需求,四种解法
java2AI系列:SpringAI 通过 Function Calling 接入外部系统
Java 通用树形结构构建与解析工具类解析
深度剖析:Java 并发三大量难题 —— 死锁、活锁、饥饿全解
别再重复造轮子了!SpringBoot对接第三方系统模板,拿来即用
Spring AI 核心原理解析:基于 1.1.4 版本拆解底层架构
华为 IODT 设备接入
自定义跨字段校验必填注解
别再System.out了!这份SpringBoot日志优雅指南,让你告别日志混乱
AI精选
