直接赋值
Test test = new Test();
Test test1 = test;
System.out.println(test);
System.out.println(test1);
这里输出的两个值是相同的,这个是将对象的引用直接赋值给另一个引用,两个引用指向的是一个对象,并没有对对象进行复制。
对象复制
对象的复制:
在堆中单独开辟一块地址空间,用于存放与该对象内容完全相同的一个对象,地址是不同的;
复制实现
Java中父类java.lang.Object提供了clone()方法
考虑到安全性问题,一方面将clone()方法的访问级别设置为protected类型,限制外部类访问;
另一方面,强制需要提供clone功能的子类实现java.lang.Cloneable接口。
Java中所有对象都继承自Object类,所以所有的类都可以实现clone()方法,但是clone()方法是protected型的,所以JAVA规定如果一个对象想要调用clone方法,必须实现Cloneable接口,否则会抛出CloneNotSupportedException。其实这个Cloneable是个空接口,只是用来标记这个类是可以clone的,所以不能将子类向上转化。
浅复制
浅复制:
只是将当前对象进行复制,内部属性对象不进行复制,复制对象的地址与原对象不同,复制对象内部属性对象地址与原对象内部属性对象相同。当修改内部属性时,将会同时影响到两个对象。
深复制
深复制:
将当前对象进行复制,并将所有的内部属性对象进行复制,复制对象的地址与原对象不同,复制对象内部属性对象地址与原对象内部属性对象不同。修改内部属性互不影响。
深复制方法
复制构造函数
继承clone()方法,添加复制构造函数将所有内部属性对象进行复制。
自定义Copyable接口
实现一套Copyable接口:
构造复制方法;
然后想要复制的类都继承该接口并复写复制方法即可。但是复制方法内的逻辑其实与复制构造类似。
序列化实现
将一个对象先序列化写入字节流,然后再读出,重新构造成一个对象,就能实现这个对象的deep copy。
相关第三方库
BeanUtils
PropertyUtils
Dozer
Kryo
Cloning等
深复制的相关我还有许多不是很理解的地方,这些只是我的一些理解与学习。
参考:
https://www.jianshu.com/p/d02a094ace4f
https://blog.csdn.net/hzycaicai2012/article/details/45564443