java的clone方法_Java的clone()方法

1. clone方法简介

clone方法返回与当前对象的一个副本对象。可以通过操作副本对象而不影响当前对象。

使用clone方法需要实现Cloneable接口。并重写Object方法中的clone方法。

需要注意的是在clone在Object中是project修饰符。因为所有类都是Object的子类,所以如果不实现clone方法,在类中可以直接使用父类的clone方法,但是其对象在别的类中不能调用clone方法。所以必须重写clone方法。

如果不实现Cloneable接口,只重写clone方法,调用则会抛出异常。

62ac6f120e20053c47abd18fa6fcc52f.png

778e783b050c5ca7bfda8976b1d548dd.png

Stu类未实现Cloneable接口所以抛出异常

f497b6a7837ce28fc9c92974c0973a34.png

2. 浅克隆与深克隆

2.1 浅克隆

看下面一个例子

1 importjava.util.Arrays;2 importjava.util.HashSet;3 importjava.util.Scanner;4 importjava.util.Set;5

6 public classTest {7

8 public static void main(String[] args) throwsCloneNotSupportedException {9 Stu stu = newStu();10 stu.name = "Tom";11 Stu stu1;12 stu1 =stu;13 System.out.println(stu==stu1);14 stu1.name = "LiMing";15 System.out.println("stu:"+stu.name+" stu1:"+stu1.name);16 stu1 =(Stu) stu.clone();17 System.out.println(stu==stu1);18 stu1.name = "Tom";19 System.out.println("stu:"+stu.name+" stu1:"+stu1.name);20 }21

22 }23 class Stu implementsCloneable{24 String name;25 @Override26 protected Object clone() throwsCloneNotSupportedException {27 //TODO Auto-generated method stub

28 return super.clone();29 }30

31 }

Stu类实现了Cloneable接口,并且重写了clone方法。

首先设stu1变量值等于stu,我们都知道stu1直接指向stu的地址。所以测试stu1==stu时,结果为true,说明两个地址相同。同时改变stu1的name值为“LiMing”,stu的name值也改为“LiMimg”。

设stu1变量值等于stu.clone(),这时stu1的指向stu对象副本的地址,测试stu1==stu,结果为false,说明两个地址不同。改变stu1的name值为"Tom",stu因为指向的对象与stu1的指向的对象不同,因此stu的name值并未改变。

测试结果

6697825382cc1c44daf603b38f35de36.png

2.2 深克隆

考虑下面这种情况

学生类包含笔类,这时在使用clone方法。

1 public classTest {2

3 public static void main(String[] args) throwsCloneNotSupportedException {4 Stu stu = newStu();5 stu.name = "Tom";6 stu.pen.name = "A";7 Stu stu1;8 stu1 =(Stu) stu.clone();9 System.out.println(stu1.pen==stu.pen);10 stu1.pen.name = "B";11 System.out.println("stu1:"+stu1.pen.name+"|stu:"+stu.pen.name);12 }13

14 }15 class Stu implementsCloneable{16 String name;17 Pen pen = newPen();18 @Override19 protected Object clone() throwsCloneNotSupportedException {20 //TODO Auto-generated method stub

21 return super.clone();22 }23

24 }25 classPen{26 String name;27 }

发现此时stu1.pen的地址与stu.pen的地址相同。所以改变stu1.pen.name的值,stu.pen.name的值也发生了相应的改变。这是因为对于引用类型,clone方法只克隆引用类型的地址。这时就用到了深克隆。

测试结果

6cfaea0496a22c21212a257724a8f067.png

深克隆:

1 public classTest {2

3 public static void main(String[] args) throwsCloneNotSupportedException {4 Stu stu = newStu();5 stu.name = "Tom";6 stu.pen.name = "A";7 Stu stu1;8 stu1 =(Stu) stu.clone();9 System.out.println(stu1.pen==stu.pen);10 stu1.pen.name = "B";11 System.out.println("stu1:"+stu1.pen.name+"|stu:"+stu.pen.name);12 }13

14 }15 class Stu implementsCloneable{16 String name;17 Pen pen = newPen();18 @Override19 protected Object clone() throwsCloneNotSupportedException {20 //TODO Auto-generated method stub

21 Stu temp = (Stu) super.clone();22 temp.pen =(Pen) pen.clone();23 returntemp;24 }25

26 }27 class Pen implementsCloneable{28 String name;29 @Override30 protected Object clone() throwsCloneNotSupportedException {31 //TODO Auto-generated method stub

32 return super.clone();33 }34 }

此时Pen类也重写了Cloneable方法。同时在重写Stu类的clone方法时先克隆Pen,在返回temp,这样temp中的pen指向克隆后的地址。

运行结果stu1.pen的地址与stu.pen的地址不在相同,改变stu1.pen.name的值而stu.pen.name的值不在改变。stu1.pen对象是一个全新的副本。

测试结果:

72132da6d7275a0f668123657ac40435.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值