克隆是什么?它的产生背景?
当new的对象是多例的时候,new对象将会不断占据内存。特别是消耗内存的大对象,比如数据库连接等。平时运用的不多,只在spring等容器有见过,此处不多赘述,了解即可。
浅克隆与深克隆是什么意思?通过案例逐步探讨。
public class Star implements Cloneable,Serializable{
private String name;
private Date birthday;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star(){}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star(String name, Date birthday) {
</span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
</span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
</span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">实现浅克隆</span>
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getName() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> name;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setName(String name) {
</span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Date getBirthday() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> birthday;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setBirthday(Date birthday) {
</span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
}
}
1 public class Client {
2 public static void main(String[] args) throws CloneNotSupportedException {
3 Date date=new Date(1346545646556465131L);
4 //new一个明星:杨洋
5 Star yangYang=new Star("杨洋",date);
6 System.out.println(yangYang);
7 System.out.println(yangYang.getName());
8 System.out.println(yangYang.getBirthday());
9
10 date.setTime(4685456456456465465L);
11 System.out.println(yangYang.getBirthday());
12
13 //克隆杨洋:满足你当明星的梦
14 Star me=(Star) yangYang.clone();
15 System.out.println(me);
16 me.setName("周杰伦");
17 System.out.println(me.getName());
18 System.out.println(me.getBirthday());
19 }
20 }
问题:我们发现,当date改变的时候,克隆对象的date也随之改变。这个不难理解,因为原型对象改变,克隆对象也随之改变,克隆对象只是克隆了star对象,并没有去克隆star对象中的birthday对象。
结论:浅克隆就是克隆对象直接引用原型对象。
public class Star2 implements Cloneable{
private String name;
private Date birthday;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star2(){}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Star2(String name, Date birthday) {
</span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
</span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
</span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
}
</span><span style="color: #008000;">//</span><span style="color: #008000;">实现深克隆</span>
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj= super.clone();
Star2 s</span>=<span style="color: #000000;">(Star2)obj;
s.birthday</span>=(Date) <span style="color: #0000ff;">this</span><span style="color: #000000;">.birthday.clone();
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> obj;
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getName() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> name;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setName(String name) {
</span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Date getBirthday() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> birthday;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setBirthday(Date birthday) {
</span><span style="color: #0000ff;">this</span>.birthday =<span style="color: #000000;"> birthday;
}
}
1 public class Client2 {
2 public static void main(String[] args) throws CloneNotSupportedException {
3 Date date=new Date(1346545646556465131L);
4 //new一个明星:杨洋
5 Star2 yangYang=new Star2("杨洋",date);
6 Star2 me=(Star2) yangYang.clone();//深克隆里面的birthday对象是一个新对象
7
8 System.out.println(yangYang);
9 System.out.println(yangYang.getName());
10 System.out.println(yangYang.getBirthday());
11
12 date.setTime(4685456456456465465L);
13 System.out.println(yangYang.getBirthday());
14
15
16 System.out.println(me);
17 me.setName("周杰伦");
18 System.out.println(me.getName());
19 System.out.println(me.getBirthday());
20 }
21 }
问题:我们发现,当date改变的时候,克隆对象的bitthday并没有随之改变。通过实体类可知,当克隆对象的时候,随之也去克隆了实体类里面的引用对象,即克隆对象的birthday是一个new的对象。
结论:深克隆就是递归克隆出原型对象里的所有引用对象。