Java中深拷贝(Deep Clone)与浅拷贝(Shallow Clone)
2012-06-02 21:53
501 查看
我们先从理论上讨论浅拷贝:
java的类型分为两大类,一类为primitive,如int等8种,另一类为引用类型,如String,Object等等。java的引用类型都是存储在堆上的。
java的浅复制在复制时,对于原始类型的变量,在堆上为其分配一块区间,对于引用类型,在堆上为其对象的引用分配一块区间,这样得到的实际效果是:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象,即当对其他对象的引用进行改变时,改变的是对象的值,被复制的引用值也发生了变化。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
实例代码如下:
再来看看深拷贝:
理论上,深复制对原始类型的操作与浅复制一样,对于引用类型,其既对对象的引用进行复制,也对对象本身进行复制,这样得到的实际效果是:当复制的引用值发生变化时,被复制的引用值没有发生变化,实现了深复制。被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
实例代码如下:
一言以蔽之:浅复制只是简单的值传递(这样一来复制的双方可能有瓜葛),而深复制则是深层次的对象传递(这样一来复制的双方不会有作何瓜葛),这里的对象传递指的是若有引用的复制则生成新的对象,而不会只是单纯地将引用指向原来的对象。
参考文献:http://java.chinaitlab.com/oop/716567.html
java的类型分为两大类,一类为primitive,如int等8种,另一类为引用类型,如String,Object等等。java的引用类型都是存储在堆上的。
java的浅复制在复制时,对于原始类型的变量,在堆上为其分配一块区间,对于引用类型,在堆上为其对象的引用分配一块区间,这样得到的实际效果是:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象,即当对其他对象的引用进行改变时,改变的是对象的值,被复制的引用值也发生了变化。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
实例代码如下:
public class CloneTest1 { public static void main(String[] args) throws Throwable { Teacher teacher = new Teacher(); teacher.setAge(34); teacher.setName("Teacher chen"); Student student = new Student(); student.setAge(20); student.setName("zhangsan"); student.setTeacher(teacher); //clone方法返回的是Object类型的对象,即会生成新的对象 Student student2 = (Student)student.clone(); System.out.println(student2.getAge()); System.out.println(student2.getName()); System.out.println(student2.getTeacher().getAge()); System.out.println(student2.getTeacher().getName()); System.out.println("----------------------------------"); /** * 以下几行说明clone是浅复制(只是复制引用),即复制后两个对象中的teacher属性都指向同一个对象, * 如果把拷贝的对象的teacher属性重新设置,则会影响被拷贝的对象。 */ student2.getTeacher().setName("hello world"); student2.getTeacher().setAge(44); student2.setName("lisi");//不会改变student的属性 System.out.println(student2.getAge()); System.out.println(student2.getName()); //student2中的teacher对象也发生了改变 System.out.println(student2.getTeacher().getAge()); System.out.println(student2.getTeacher().getName()); System.out.println("----------------------------------"); System.out.println(student.getAge()); System.out.println(student.getName()); System.out.println(student.getTeacher().getAge()); System.out.println(student.getTeacher().getName()); } } class Student implements Cloneable { private int age; private String name; private Teacher teacher; public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { Object object = super.clone(); return object; } } class Teacher implements Cloneable { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
再来看看深拷贝:
理论上,深复制对原始类型的操作与浅复制一样,对于引用类型,其既对对象的引用进行复制,也对对象本身进行复制,这样得到的实际效果是:当复制的引用值发生变化时,被复制的引用值没有发生变化,实现了深复制。被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
实例代码如下:
//深复制 public class CloneTest2 { public static void main(String[] args) throws Throwable { Teacher2 teacher = new Teacher2(); teacher.setAge(40); teacher.setName("Teacher zhang"); Student2 s1 = new Student2(); s1.setAge(20); s1.setName("zhangsan"); s1.setTeacher(teacher); Student2 s2 = (Student2)s1.clone(); System.out.println(s2.getName()); System.out.println(s2.getAge()); /** * 因为下面Student2中的clone方法也实现了对Teacher对象的拷贝, * 所以在s2中已经拥有了新的Teacher对象,不再是前面传给s1的那个Teacher对象, * 故下面这句只是改变了s1中的那个Teacher对象,而不会改变s2中的那个Teacher对象。 */ teacher.setName("Teacher li"); System.out.println(s1.getTeacher().getName()); System.out.println(s1.getTeacher().getAge()); System.out.println(s2.getTeacher().getName()); System.out.println(s2.getTeacher().getAge()); } } class Teacher2 implements Cloneable { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } //只是为了在其他类中可以调用Teacher中的这个clone方法,所以重写为public @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } class Student2 implements Cloneable { private int age; private String name; private Teacher2 teacher; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Teacher2 getTeacher() { return teacher; } public void setTeacher(Teacher2 teacher) { this.teacher = teacher; } @Override public Object clone() throws CloneNotSupportedException { Student2 student2 = (Student2)super.clone(); //把Teacher对象也复制一份,相当于有两个Teacher对象了 student2.setTeacher((Teacher2)student2.getTeacher().clone()); return student2; //下面这种方法只能实现浅复制 // Object object = super.clone(); // // return object; } }
一言以蔽之:浅复制只是简单的值传递(这样一来复制的双方可能有瓜葛),而深复制则是深层次的对象传递(这样一来复制的双方不会有作何瓜葛),这里的对象传递指的是若有引用的复制则生成新的对象,而不会只是单纯地将引用指向原来的对象。
参考文献:http://java.chinaitlab.com/oop/716567.html
相关文章推荐
- java浅拷贝(shallow clone)与深拷贝(deep clone)
- java shallow clone(浅克隆)与深克隆(deep clone) 笔记
- Java中shallow clone 与deep Clone的区别
- java语言——对象的深复制(deep clone)与浅复制(shallow clone)
- JAVA中的深度克隆(deep clone) 和 影子克隆(shallow clone)浅析
- Java Clone, Shallow Copy and Deep Copy
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- Java中shallow clone 与deep Clone的区别
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- Java:浅克隆(shallow clone)与深克隆(deep clone)
- java语言——对象的深复制(deep clone)与浅复制(shallow clone)
- 深拷贝(deep clone)与浅拷贝(shallow clone)
- Java clone方法深拷贝浅拷贝完全解析
- .NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)
- java中深拷贝和浅拷贝区别
- java中深拷贝浅拷贝分析
- java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))
- 浅拷贝和深拷贝(shallow copy VS deep copy )
- IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解(shallow copy and deep copy)