浅克隆与深度克隆
来源:互联网 发布:qq空间钓鱼网站源码 编辑:程序博客网 时间:2024/05/12 19:00
1、为什么要克隆
我们在编写程序的时候,常常需要进行对象的拷贝(例如:把student1拷贝给student2),拷贝的对象要求是独立的,与母本没联系。而一般的赋值操作符只是把对象的引用复制过去,两者指向同一块内存,这样的话当改变student1的属性时,student2也会改变,这不是我们想要的结果。这时候就需要进行克隆。
2、克隆分类
1)浅克隆:进行浅克隆时,开辟一块新的内存把student1对象所占的内存块原封不动的拷贝过去给student2。
如图:
2)深度克隆:注意到上面的图,对于基本类型的变量name、age,浅克隆把它们的值从student1拷贝给student2得到两份一样的值。而对于引用类型courseGrade,拷贝的只是courseGrade的一个引用,这两个引用指向同一个courseGrade对象。这又跟之前的直接赋值操作类似了,改变student1的courseGrade属性,student2也会跟着改变。因此,浅克隆适合对于全部是基本类型的对象。对于有对象的嵌套的对象要用深克隆。通过深克隆,两对象student1、student2指向的courseGrade对象是不同的。
如图:
3.克隆的实现
1)浅克隆的实现:浅克隆的实现比较简单,我们首先要实现Cloneable接口,它是一个标记接口,没用任何方法。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用在Object类中定义的clone()方法克隆,Object类定义的克隆方法是属于浅克隆的。因为Object类是任何其他类的父类,所以,我们只需要super.clone()就可以进行浅克隆了。再者,我们定义的类是要给其他类用的,所以,一般我们会覆盖clone()方法。代码如下:
public class Student implements Cloneable{ private String name; private int yearOld; private CourseGrade courseGrade; /*******************/ @Override public Object clone() throws CloneNotSupportedException{ Student student=null; student=(Student)super.clone(); return student; }}2)深克隆的实现:深度克隆的实现主要有两种方法。
1>先来个super.clone()把基本类型给浅克隆过去,然后再对引用类型的对象克隆后赋值给克隆体的这个属性,如果这个引用类型的对象下面还有引用类型,也进行同样的操作,即克隆到底!因此,可以看出,这种深度克隆的方法只适合于层次少的类。代码如下:
public class Student implements Cloneable{ private String name; private int yearOld; private CourseGrade courseGrade; /*******************/ @Override public Object clone() throws CloneNotSupportedException{ Student student=null; student=(Student)super.clone(); student.courseGrade=(CourseGrade)this.courseGrade.clone(); return student; }}public class CourseGrade implements Cloneable{ private int chineseGrade; private int mathGrade; private int EnglishGrade; /*******************/ @Override public Object clone() throws CloneNotSupportedException{ return super.clone(); }}
2>利用序列化和反序列化来实现,这种克隆方式不管你的类层次有多深,都能一步搞定。唯一的要求是克隆的类及下面层的类都要实现Serializable接口,这个接口同样没有提供任何方法,是标记接口,实现这个接口的类才可被序列化。代码如下:
public class Student implements Serializable{ private String name; private int yearOld; private CourseGrade courseGrade; /*******************/ @Override public Object clone() throws CloneNotSupportedException{ Student student=null; try { ByteArrayOutputStream bu=new ByteArrayOutputStream(); ObjectOutputStream ou=new ObjectOutputStream(bu); ou.writeObject(this); ByteArrayInputStream bi=new ByteArrayInputStream(bu.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); student=(Student)oi.readObject(); } catch (IOException ex) { //Logger.getLogger(Student.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { //Logger.getLogger(Student.class.getName()).log(Level.SEVERE, null, ex); } return student; }}public class CourseGrade implements Serializable{ private int chineseGrade; private int mathGrade; private int EnglishGrade; /*******************/}
4、克隆后的结果
主类代码如下:
public class Test1 { /** * @param args the command line arguments */ public static void main(String[] args) throws CloneNotSupportedException { // TODO code application logic here CourseGrade courseGrade=new CourseGrade(100,100,100); Student student1=new Student("小明",20,courseGrade); System.out.println("克隆前student1属性"); System.out.println("姓名:"+student1.getName()+"||年龄:"+student1.getYearOld()+"||语文成绩:"+student1.getCourseGrade().getChineseGrade()); Student student2=(Student)student1.clone(); student2.setName("小红"); student2.setYearOld(15); student2.getCourseGrade().setChineseGrade(90); System.out.println("克隆后修改student2属性,student1和student2的变化"); System.out.println("姓名:"+student1.getName()+"||年龄:"+student1.getYearOld()+"||语文成绩:"+student1.getCourseGrade().getChineseGrade()); System.out.println("姓名:"+student2.getName()+"||年龄:"+student2.getYearOld()+"||语文成绩:"+student2.getCourseGrade().getChineseGrade()); } }
1)浅克隆结果:
克隆前student1属性姓名:小明||年龄:20||语文成绩:100克隆后修改student2属性,student1和student2的变化姓名:小明||年龄:20||语文成绩:90姓名:小红||年龄:15||语文成绩:90
2)深度克隆结果:
克隆前student1属性姓名:小明||年龄:20||语文成绩:100克隆后修改student2属性,student1和student2的变化姓名:小明||年龄:20||语文成绩:100姓名:小红||年龄:15||语文成绩:90
- 浅克隆与深度克隆
- 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- 深度克隆与浅度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- Java clone() 浅克隆与深度克隆
- IAP内购破解原理
- 哈夫曼树和哈夫曼编码
- linux 编译指定库、头文件的路径问题
- 怎么改博客页面顶上的信息
- [jQuery1.9]Cannot read property ‘msie’ of undefined错误的解决方法
- 浅克隆与深度克隆
- 少年不可欺:自媒体维权的范本
- HDU 1242 Rescue 【DFS】
- DevExpress 合并单元格设置
- Linux内核使用三种不同的版本编号方式。
- 付出等与回报
- json and string (Ruby)
- android 情景模式来电铃声分析(三)
- 放下