为什么要clone
有两个独立的对象A和B,A在某一刻的属性需要保存下来,而B用来记录A的状态,简单的赋值不满足需求,因为java默认是传递对象的引用,不会进行对象的复制,指向的空间是同一个。clone是满足需求的。
克隆的原理
克隆中要考虑到的问题?
数据类型分为基本数据类型和引用数据类型,引用类型的clone是否需要新的副本?不需要的为浅克隆,需要的为深克隆。具体实现如下:
浅克隆
public class Persion implements Cloneable{
String persionName;
int age;
Head head;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
测试结果如下
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@1540e19d}com.shqp.clone.Persion@74a14482本体
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@1540e19d}com.shqp.clone.Persion@74a14482简单赋值
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@677327b6}com.shqp.clone.Persion@14ae5a5深复制
深克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Persion p = (Persion) super.clone();
p.head = (Head) head.clone();
return p;
}
public class Head implements Cloneable{
String hName;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
测试结果如下`
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@1540e19d}com.shqp.clone.Persion@74a14482本体
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@1540e19d}com.shqp.clone.Persion@74a14482简单赋值
Persion{persionName='张三', age=2, head=Head{hName='长发'}com.shqp.clone.Head@677327b6}com.shqp.clone.Persion@14ae5a5深复制
怎样实现克隆
- 实现Cloneable接口:接口只有提示作用没有实际方法
- 重写clone方法:将Object类的本地方法拓展成可调用的方法
- 深克隆:在外层类的clone方法中将内层类对象也克隆一份(内层类也要执行1和2)
新的问题:层层嵌套的类怎要实现克隆
序列化反序列化