下面第一部分文字描述来源于:http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html
源代码自写。
深克隆浅克隆简要描述、浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的 引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象
深复制(深克隆)被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原
有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
浅度克隆步骤:
1、实现java.lang.Cloneable接口 2、重写java.lang.Object.clone()方法在浅度克隆的基础上,对于要克隆的对象中的非基本数据类型的属性对应的类,也实现克隆;这样对于非基本数据类型的属性,复制的不是一份引用,即新产生的对象和原始对象中的非基本数据类型的属性指向的不是同一个对象 。
深度克隆步骤:
要克隆的类和类中所有非基本数据类型的属性对应的类 1、都实现java.lang.Cloneable接口 2、都重写java.lang.Object.clone()方法Java的clone()方法
⑴ clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象 ②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样 ③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。⑵ Java中对象的克隆
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。 ②在派生类中覆盖基类的clone()方法,并声明为public。 ③在派生类的clone()方法中,调用super.clone()。 ④在派生类中实现Cloneable接口。源代码部分(首先实现克隆):
本部分分为两个部分,一部分为实现克隆设计类的功能,另外一部分为测试设计的类的功能是否成功执行。 第一部分: public class Student implements Cloneable{ String name; int age; public Student (String name, int age) { this.name = name; this.age = age; } public Object clone() { Student o = null; try { o = (Student)super.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); } return o; } } 第二部分: public class CloneTest { /***对象克隆*/ public static void main(String[] args) { Student a = new Student("zhangsan",23); Student b = (Student)a.clone(); System.out.println(b.name+" , "+b.age); b.book = "wangwu"; System.out.println(a.name+" , "+a.age); } } 以上为克隆,就是复制对象的所有变量都与原来的对象相同的值。内存变化如下所示:
其次实现浅克隆,代码仿照上面分成两部分:
第一部分(分为 两个类): 第一部分第一个类: class Book{ String bookName = "java"; } 第一部分第二个类: public class Student implements Cloneable{ String name; int age; Book b; public Student (String name, int age, Book b) { this.name = name; this.age = age; this.b = b; } public Object clone() { Student o = null; try { o = (Student)super.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); } return o; } } 第二部分(测试上面两个类的功能): public class CloneTest { /***对象克隆*/ public static void main(String[] args) { Book ba = new Book(); Student a = new Student("zhangsan",23,ba); Student b = (Student)a.clone(); System.out.println(b.name+" , "+b.age+" ,book: "+b.b.bookName); a.b.bookName = "c语言"; System.out.println(b.name+" , "+b.age+" ,book: "+b.b.bookName); } } 结果: zhangsan,23,book:java zhangsan,23,book:c语言 我们发现修改a对象的Book,导致b对象的Book名称也发生了改变,也就是克隆时,没有克隆Book,两个学生,引用的是同一本书。内存中的结构图如下所示:(浅克隆的内存结构图:)
而我们所需要的深克隆是这样的,(内存中的结构图如下所示:)
深克隆的代码如下,同样也是分为两个部分:
深克隆第一部分(有两个类组成): 第一部分(第一个类) public class Book implements Cloneable{ String bookName = "java"; public Object clone() { Object o = null; try { o = super.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); } return o; } } 第一部分(第二个类) public class Student implements Cloneable{ String name; int age; Book b; public Student (String name, int age, Book b) { this.name = name; this.age = age; this.b = b; } public Object clone() { Student o = null; try { //调用方法 o = (Student)super.clone(); o.b = (Book)b.clone(); } catch(CloneNotSupportedException e) { e.printStackTrace(); } return o; } } 第二部分: public class CloneTest { /***对象克隆*/ public static void main(String[] args) { Book ba = new Book(); Student a = new Student("zhangsan",23,ba); Student b = (Student)a.clone(); System.out.println(b.name+" , "+b.age+" ,book: "+b.b.bookName); a.b.bookName = "c语言"; System.out.println(b.name+" , "+b.age+" ,book: "+b.b.bookName); System.out.println(a.name+" , "+a.age+" ,book: "+a.b.bookName); } } 结果:(成功实现了深克隆!) zhangsan,23,book:java zhangsan,23,book:java zhangsan,23,book:c语言