码迷,mamicode.com
首页 > 编程语言 > 详细

java的深拷贝和浅拷贝

时间:2015-01-20 12:11:22      阅读:162      评论:0      收藏:0      [点我收藏+]

标签: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的深拷贝和浅拷贝

标签:java 深拷贝 浅拷贝

原文地址:http://793404905.blog.51cto.com/6179428/1606011

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!