与python中深浅拷贝一样的,这里主要是介绍api。对于深拷贝,只要记住一点:深拷贝API都是非递归的方式
Java获取对象地址:
https://blog.csdn.net/zhoufanyang_china/article/details/86750351
Java对象hashcode计算:所有对象都有hashcode,hashcode并不是由对象地址计算得到的,不能用于判断两个对象是否是同一个对象,上面和下面两个教程都可以说明
https://blog.csdn.net/baidu_37107022/article/details/75946383
一 概述
- 深浅拷贝都是对于对象而言的,基本数据类型不存在深拷贝、浅拷贝,因为基本数据类型的值都是字面值常量(相当于原子),是独一份的,不存在修改问题。而对象是字面常量值的组合,可能发生变化。
- 浅拷贝,指的是新旧引用变量指向同一块内存。深拷贝,指的创建一个对象,新的引用变量指向新的对象。问题在于,Java、Python这些面对对象的语言,对象的成员变量依然是指向其他对象的引用变量,这种情况也就是所谓的嵌套。
- 已有的深拷贝API都是只进行一层深拷贝,而不是递归地拷贝整个引用链。所以只在恰好只封装了一层时,才会如希望的那样起作用,这时对象内的元素是直接指向基本数据类型的。
上图中,对象可以是自定义对象,也可以是集合对象。可以看到深拷贝也不过如此。而实际希望的深拷贝是如下所示的:
这种深拷贝没有现成的API,要通过序列化、反序列化实现。
二 实现
深浅拷贝要从基本数据类型开始一层一层数。自定义类对象,集合类对象,都算是进行一层封装。将自定义对象作为类的成员变量、作为集合参数,集合数据类型进行封装,这都算是嵌套封装。
严格来说,stream、CollectionUtils、clone都是浅拷贝,但是这些又与直接赋值有区别,因此,便于理解,个人称其为一层深拷贝
深拷贝API:
- 集合对象深拷贝:stream()、CollectionUtils;
- 自定义类对象深拷贝:clone();
貌似不存在现成的完全深拷贝的API,就算用序列化、反序列化,也是专门针对一个类写的。
2.1 集合对象 + X
不嵌套: 集合对象(外)+ 基本数据类型(内)
List<String> tmp = new ArrayList<>();
tmp.add("a");
tmp.add("b");
System.out.println(tmp);
// 输出:
// [a, b]
List<String> tmp2 = tmp;
tmp2.add("c"