标签:java 深拷贝 浅拷贝
最近看一些书籍,深拷贝和浅拷贝的字样,总是浮现在眼前,于是乎整理了一下,关于java的深浅拷贝原理和实现。
1. 什么是深/浅拷贝?
浅拷贝:对目标对象的基本数据类型值的复制和引用类型的地址的复制;
深拷贝:对目标对象的基本数据类型值的复制以及应用类型值复制(专业点称之为动态内存)。
从概念上分很难以理解,下图列出了两者的区别:
1)浅拷贝
上图中,左侧是原始对象(基本数据类型、引用类型),但使用浅拷贝方式生成一个新对象,使得新对象的基本类型数值与原始对象一致,但是引用数据类型会指向原始对象引用类型,因此当原始对象和浅拷贝对象任何一方修改了引用类型的值,那么另一方也会发生改变。因为两者指向同一个对象。
2)深拷贝
从上图可以发现原始对象和深拷贝对象两者没用引用连接关系。深拷贝实际执行的是生成一个新的对象,基本数据类型与原始对象一直,引用数据类型通过原始对象引用数据类型值构造的新对象。通俗点说就是深拷贝对象的引用数据与原始对象的引用数据值相同,但不是同一个对象,不指向同一块地址。
2. java实现深/拷贝
public class Student { private String name; private int age; public Student(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Classes implements Cloneable{ private String className; private Student student; public Classes(String className, Student student){ this.className = className; this.student = student; } /** * 默认实现的是浅拷贝 */ @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } /** * 深拷贝 : 新建立一个对象 * @return */ public Classes deepCopy() { Classes classes = new Classes(this.getClassName(), new Student(this.getStudent().getName(), this.getStudent().getAge())); return classes; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } } // 测试代码 public class TestCopy { @Test public void testShallowCopy() throws CloneNotSupportedException{ Classes classes = new Classes("信计091", new Student("wangzp", 23)); // 浅拷贝,新创建一个对象,然后拷贝基本数据类型数值,引用类型地址 Classes classes1 = (Classes)classes.clone(); System.out.println(classes.getStudent() == classes1.getStudent());//true } @Test public void testDeepCopy(){ Classes classes = new Classes("信计091", new Student("wangzp", 23)); Classes classes1 = classes.deepCopy(); System.out.println(classes1.getStudent() == classes.getStudent());//false } }
3. 深/浅拷贝的差异
从2中代码实现,可以发现深拷贝是重新构造对象的过程,因此效率并不是很好。而浅拷贝由于拷贝对象与原始对象之间引用对象是共享的,因此容易导致任意一方修改引用类型属性,而另一方也修改了,容易导致错误的发生。
一般而言,如果原始对象变量多为基本数据类型,且引用类型不常修改,建议使用浅拷贝;反之建议使用深拷贝。
本文出自 “java程序冥” 博客,请务必保留此出处http://793404905.blog.51cto.com/6179428/1606011
标签:java 深拷贝 浅拷贝
原文地址:http://793404905.blog.51cto.com/6179428/1606011