JAVA 对象克隆clone
来源:互联网 发布:合同档案管理系统软件 编辑:程序博客网 时间:2024/05/18 21:38
有时候我们希望克隆一个已存在的对象,并对其进行操作,但是不希望改变原对象,这时使用clone技术就非常方便了。但是使用clone,也有一些需要注意的地方,因为clone有浅层克隆和深层克隆。还是习惯先直接上代码,结合代码讲解。
注:如果你希望某个类具有clone功能,该类必须实现接口Cloneable,它是一个标识接口,告诉JVM,这个类具有clone权利。
为了方便测试,以下代码写得很随便,没有按照规范些,呵呵。
public class A implements Cloneable{//为了方便测试,以下变量都用public修饰public int num;public String name;public String[] nickNames=new String[2];public B b=new B();public A clone(){A a=null;try{a=(A)super.clone();}catch(CloneNotSupportedException e){e.printStackTrace();}return a;}}
public class B {//为了方便测试,变量用public修饰public String name;}
public class C {public static void main(String[] args){A a1=new A();//给a1的属性设值a1.num=10;a1.name="a1";a1.nickNames[0]="a1-1";a1.nickNames[1]="a1-2";a1.b.name="a1.b";//打印a1System.out.println("a1克隆前:");print(a1);A a2=a1.clone();//给a2属性设值a2.num=20;a2.name="a2";a2.nickNames[0]="a2-1";a2.nickNames[1]="a2-2";a2.b.name="a2.b";//打印a2System.out.println("克隆对象a2:");print(a2);//再打印a1System.out.println("a1克隆后:");print(a1);}public static void print(A a){System.out.println("num="+a.num+" name="+a.name+" nickNames[0]="+a.nickNames[0]+" nickNames[1]="+a.nickNames[1]+" b.name="+a.b.name);}}
看看运行结果:
a1克隆前:
num=10 name=a1 nickNames[0]=a1-1 nickNames[1]=a1-2 b.name=a1.b
克隆对象a2:
num=20 name=a2 nickNames[0]=a2-1 nickNames[1]=a2-2 b.name=a2.b
a1克隆后:
num=10 name=a1 nickNames[0]=a2-1 nickNames[1]=a2-2 b.name=a2.b
发现a1除了int num,String name的内容没变,其它都变了,这是怎么回事呢?这就是所谓的浅层克隆,也就是克隆不彻底,画张草图表示下.
发现虽然引用对象a1和引用对象a2都指向了各自的实例对象,但是他们的实例对象内部的数组对象和类对象引用(除了String)都指向了同一处。为了解决这问题,就需要深层克隆。
A代码修改如下。
public class A implements Cloneable{//为了方便测试,以下变量都用public修饰public int num;public String name;public String[] nickNames=new String[2];public B b=new B();public A clone(){A a=null;try{a=(A)super.clone();a.nickNames=new String[this.nickNames.length];//重新new一个System.arraycopy(this.nickNames, 0, a.nickNames, 0, this.nickNames.length);//复制a.b=(B)this.b.clone();//B克隆}catch(CloneNotSupportedException e){e.printStackTrace();}return a;}}
由于A中对B进行了克隆,所以B也必须实现接口Cloneable
public class B implements Cloneable{//为了方便测试,变量用public修饰public String name;public B clone(){B b=null;try{b=(B)super.clone();}catch(CloneNotSupportedException e){e.printStackTrace();}return b;}}
测试类C不需修改,再看看运行结果。
a1克隆前:
num=10 name=a1 nickNames[0]=a1-1 nickNames[1]=a1-2 b.name=a1.b
克隆对象a2:
num=20 name=a2 nickNames[0]=a2-1 nickNames[1]=a2-2 b.name=a2.b
a1克隆后:
num=10 name=a1 nickNames[0]=a1-1 nickNames[1]=a1-2 b.name=a1.b
发现a2就算进行了修改也无法影响到a1了,这就是我们要的效果
- java对象克隆clone
- java 对象 克隆 clone
- Java clone()克隆对象
- JAVA 对象克隆clone
- java对象克隆clone
- Java 对象克隆(clone)
- Java| Java对象克隆Clone(1)
- Java| Java对象克隆Clone(2)
- java对象克隆之深度克隆 deep clone
- 对象的克隆(clone)
- 对象的克隆(clone)
- php 对象克隆 clone
- 对象的克隆clone
- PHP克隆对象clone
- js 克隆对象clone
- java克隆(Clone)
- java 克隆clone
- java Clone()克隆
- Mysql中排序在SQL优化中的部分解析
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析
- 分布式ID的简单实现
- 报错集锦
- SQLite3 C/C++ 开发接口简介(API函数)
- JAVA 对象克隆clone
- EJB3.0 查询语言JPQL用法
- VS字符串时间转换用法
- Linux系统中进程与作业的管理
- Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(Frame Buffer)的管理分析
- HDU 1160 FatMouse's Speed
- mysql ifnull()函数
- phonegap 学习简述
- Java Servlet Hello World with Tomcat