码迷,mamicode.com
首页 > 编程语言 > 详细

Java的clone()方法

时间:2018-10-03 20:34:07      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:sys   例子   als   ted   throws   Stub   rri   new   object   

1. clone方法简介

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

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

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

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

技术分享图片

技术分享图片

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

技术分享图片

 

2. 浅克隆与深克隆

2.1 浅克隆

看下面一个例子

 1 import java.util.Arrays;
 2 import java.util.HashSet;
 3 import java.util.Scanner;
 4 import java.util.Set;
 5 
 6 public class Test {
 7     
 8     public static void main(String[] args) throws CloneNotSupportedException {
 9         Stu stu = new Stu();
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 implements Cloneable{
24     String name;
25     @Override
26     protected Object clone() throws CloneNotSupportedException {
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值并未改变。

测试结果

技术分享图片

2.2 深克隆

考虑下面这种情况

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

 1 public class Test {
 2     
 3     public static void main(String[] args) throws CloneNotSupportedException {
 4         Stu stu = new Stu();
 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 implements Cloneable{
16     String name;
17     Pen pen = new Pen();
18     @Override
19     protected Object clone() throws CloneNotSupportedException {
20         // TODO Auto-generated method stub
21         return super.clone();
22     }
23     
24 }
25 class Pen{
26     String name;
27 }

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

测试结果

技术分享图片

深克隆:

 1 public class Test {
 2     
 3     public static void main(String[] args) throws CloneNotSupportedException {
 4         Stu stu = new Stu();
 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 implements Cloneable{
16     String name;
17     Pen pen = new Pen();
18     @Override
19     protected Object clone() throws CloneNotSupportedException {
20         // TODO Auto-generated method stub
21         Stu temp = (Stu) super.clone();
22         temp.pen = (Pen) pen.clone();
23         return temp;
24     }
25     
26 }
27 class Pen implements Cloneable{
28     String name;
29     @Override
30     protected Object clone() throws CloneNotSupportedException {
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对象是一个全新的副本。

测试结果:

技术分享图片

 

Java的clone()方法

标签:sys   例子   als   ted   throws   Stub   rri   new   object   

原文地址:https://www.cnblogs.com/lolybj/p/9738946.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!