一、概念
1、概念
在Java中,对象的拷贝分为深拷贝和浅拷贝,这两个概念描述了对象拷贝的方式和效果。
浅拷贝(Shallow Copy):
浅拷贝是指在拷贝对象时,仅复制对象本身和其内部的基本数据类型字段,而不会复制引用类型字段所引用的对象。这意味着新对象和原始对象会共享同一个引用对象,修改其中一个对象的引用字段会影响到另一个对象。简单来说,浅拷贝只是创建了一个指向原始对象的新对象的引用。
深拷贝(Deep Copy):
深拷贝是指在拷贝对象时,不仅复制对象本身和其内部的基本数据类型字段,还会递归复制引用类型字段所引用的对象。这样,新对象和原始对象将完全独立,对任何一个对象的修改都不会影响到另一个对象。简而言之,深拷贝会创建一个全新的对象及其所有关联的对象。
实现深拷贝的方式可以是通过实现Cloneable接口并重写clone()方法,或者使用序列化和反序列化等方法来复制对象及其引用的对象。需要根据具体的需求选择适合的方式进行深拷贝操作。
需要注意的是,浅拷贝和深拷贝的概念适用于对象的拷贝操作,而不同于对象的赋值操作。在赋值操作中,无论是基本数据类型还是引用类型,都只是将一个对象的引用赋值给了另一个对象,它们仍然指向同一个对象,修改其中一个对象会影响到另一个对象。
2、对比
简单地址值复制
内容完全一致,只是由2个变量值,进行取值使用(user01
、user02
)。
User user01 = new User(); User user02 = user01;
覆盖子集的地址值的复制
借助一定的API,表明子集的类型。能够实现对子集地址值(obj02
)的覆盖。当子集中obj02
数据变更,则复制后值也变更。
完全的深拷贝
目前只能借助格式化来实现,可以采用流进行复制,也可以借助JSON格式化来实现。
3、常用API整理
二、浅拷贝
1、实体类
核心API
import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(user01, user02);
代码:
User user01 = new User("张三", 18, "北京"); User user02 = new User(); BeanUtils.copyProperties(user01, user02); System.out.println(user01.equals(user02)); System.out.println(user01); System.out.println(user02); System.out.println("====更新值===="); user01.setName("王五"); System.out.println(user01); System.out.println(user02);
结果:
true User(name=张三, age=18, address=北京) User(name=张三, age=18, address=北京) ====更新值==== User(name=王五, age=18, address=北京) User(name=张三, age=18, address=北京)
2、Map类型
核心API
HashMap<String, String> newMap01 = new HashMap<>(hashMap); newMap02.putAll(hashMap);
代码:
HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("key01", "value01"); hashMap.put("key02", "value02"); hashMap.put("key03", "value03"); // 浅拷贝 HashMap<String, String> newMap01 = new HashMap<>(hashMap); HashMap<String, String> newMap02 = new HashMap<>(); newMap02.putAll(hashMap); System.out.println(hashMap); System.out.println(newMap01); System.out.println(newMap02);
结果:
{key03=value03, key02=value02, key01=value01} {key03=value03, key02=value02, key01=value01} {key03=value03, key02=value02, key01=value01} {level02={key01=value01}} {level02={key01=value01}}
反例(不支持深拷贝):
// 反例 HashMap<String, Map> level01 = new HashMap<>(); HashMap<String, String> level02 = new HashMap<>(); level02.put("key01", "value01"); level01.put("level02", level02); HashMap<String, Map> newLevel = new HashMap<>(level01); System.out.println(level01); System.out.println(newLevel); System.out.println("更新值后"); level02.put("key01", "======"); System.out.println(level01); System.out.println(newLevel);
{level02={key01=value01}} {level02={key01=======}}
3、数组
核心API
int[] arr2 = Arrays.copyOf(arr1, arr1.length);
// 复制数组解析: (原数组,从原数组的起始位置,目标数组,目标数组的起始位置,要复制的数组长度) System.arraycopy(arr1, 0, arr3, 0, arr1.length);
代码:
int[] arr1 = {1, 2, 3, 4, 5}; int[] arr2 = Arrays.copyOf(arr1, arr1.length); int[] arr3 = new int[arr1.length]; // 复制数组解析: (原数组,从原数组的起始位置,目标数组,目标数组的起始位置,要复制的数组长度) System.arraycopy(arr1, 0, arr3, 0, arr1.length); System.out.println(JSON.toJSONString(arr1)); System.out.println(JSON.toJSONString(arr2)); System.out.println(JSON.toJSONString(arr3));
结果:
[1,2,3,4,5] [1,2,3,4,5] [1,2,3,4,5]
4、集合
核心API
// 复制对象值的拷贝 import cn.hutool.core.bean.BeanUtil; List<User> arrayLists = BeanUtil.copyToList(users, User.class); 浅拷贝: users03.addAll(users); ArrayList<User> users04 = new ArrayList<>(users);
代码:
User user03 = new User("张三", 18, "北京"); User user04 = new User("李四", 19, "天津"); ArrayList<User> users = new ArrayList<>(); users.add(user03); users.add(user04); List<User> arrayLists = BeanUtil.copyToList(users, User.c ArrayList<User> users03 = new ArrayList<>(); users03.addAll(users); ArrayList<User> users04 = new ArrayList<>(users); // 打印初始值 System.out.println(JSON.toJSONString(users)); System.out.println(JSON.toJSONString(arrayLists)); System.out.println(JSON.toJSONString(users03)); System.out.println(JSON.toJSONString(users04)); System.out.println("===="); // 更新某个对象值 user03.setName("ddddd"); System.out.println(JSON.toJSONString(users)); System.out.println(JSON.toJSONString(arrayLists)); System.out.println(JSON.toJSONString(users03)); System.out.println(JSON.toJSONString(users04));
结果:
[{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}] ==== [{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"张三"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}] [{"address":"北京","age":18,"name":"ddddd"},{"address":"天津","age":19,"name":"李四"}]
5、JSONObject
核心API
obj02.putAll(obj01);
代码:
JSONObject one = new JSONObject(); one.put("one", "fish"); JSONObject two = new JSONObject(); two.putAll(one); // 打印初始值 System.out.println("init: one: " + one.toString()); System.out.println("init: two: " + two.toString()); // 更改值 one.put("one", "fish======="); System.out.println("init: one: " + one.toString()); System.out.println("init: two: " + two.toString());
2层子对象
JSONObject obj01 = new JSONObject(); JSONObject obj01_01 = new JSONObject(); obj01.put("dd111", obj01_01); obj01_01.put("key01", "value01"); JSONObject obj02 = new JSONObject(); obj02.putAll(obj01); // 打印初始值 System.out.println(obj01); System.out.println(obj02); // 更改值 obj01_01.put("dd111", "value01============="); System.out.println(obj01); System.out.println(obj02);
结果:
init: one: {"one":"fish"} init: two: {"one":"fish"} init: one: {"one":"fish======="} init: two: {"one":"fish"} ============================================================ {"dd111":{"key01":"value01"}} {"dd111":{"key01":"value01"}} {"dd111":{"key01":"value01","dd111":"value01============="}} {"dd111":{"key01":"value01","dd111":"value01============="}}
6、JsonArray
核心API
JSONArray jsonArray02 = (JSONArray) jsonArray01.clone(); jsonArray03.addAll(jsonArray01);
代码:
JSONArray jsonArray01 = new JSONArray(); jsonArray01.add("test01"); jsonArray01.add("test02"); jsonArray01.add("test03"); JSONArray jsonArray02 = (JSONArray) jsonArray01.clone(); JSONArray jsonArray03 = new JSONArray(); jsonArray03.addAll(jsonArray01); // 打印初始值 System.out.println(jsonArray01); System.out.println(jsonArray02); System.out.println(jsonArray03);
子集值,更新
JSONArray jsonArray01 = new JSONArray(); jsonArray01.add("test01"); jsonArray01.add("test02"); jsonArray01.add("test03"); JSONObject one = new JSONObject(); one.put("one", "fish"); jsonArray01.add(one); JSONArray jsonArray05 = (JSONArray) jsonArray01.clone() JSONArray jsonArray06 = new JSONArray(); jsonArray06.addAll(jsonArray01); // 打印初始值 System.out.println(jsonArray01); System.out.println(jsonArray05); System.out.println(jsonArray06); // 值更新 one.put("two", "two"); System.out.println(jsonArray01); System.out.println(jsonArray05); System.out.println(jsonArray06);
结果:
["test01","test02","test03"] ["test01","test02","test03"] ["test01","test02","test03"] --- ["test01","test02","test03",{"one":"fish"}] ["test01","test02","test03",{"one":"fish"}] ["test01","test02","test03",{"one":"fish"}] ["test01","test02","test03",{"one":"fish","two":"two"}] ["test01","test02","test03",{"one":"fish","two":"two"}] ["test01","test02","test03",{"one":"fish","two":"two"}]
三、深拷贝
实体类
User user = new User(); String s = JSON.toJSONString(user); User userClone = JSON.parseObject(s, User.class);
Map
HashMap<String, String> hashMap = new HashMap<>(); String s1 = JSON.toJSONString(hashMap); HashMap hashMap1 = JSON.parseObject(s, HashMap.class);
List集合
ArrayList<User> users = new ArrayList<>(); String s2 = JSON.toJSONString(users); ArrayList arrayList = JSON.parseObject(s2, ArrayList.class);
JSONObject
JSONObject jsonObject = new JSONObject(); String s3 = jsonObject.toJSONString(); JSONObject jsonObject1 = JSON.parseObject(s3, JSONObject.class);
JSONArray
JSONArray jsonArray = new JSONArray(); String s4 = jsonArray.toJSONString(); JSONArray jsonArray1 = JSON.parseObject(s4, JSONArray.class);
四、XMind文件
https://download.csdn.net/download/weixin_44624117/87778427