博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中的浅拷贝与深拷贝
阅读量:7193 次
发布时间:2019-06-29

本文共 5404 字,大约阅读时间需要 18 分钟。

hot3.png

什么是浅拷贝?

浅拷贝本质上和深拷贝并没有什么区别,只是当被拷贝的对象内部包含着其他的对象时,浅拷贝只是将那个所谓的其他对象的引用拷贝出来到第二个对象中,那么在内存中,这个所谓的其他对象实际上是同时被original对象和新拷贝的对象所引用;即它们共用同一内存区域。在Java中,Object.clone()实现的。默认情况下,如果直接调用super.clone(),是浅拷贝的。

The default version of clone() method creates the shallow copy of an object. The shallow copy of an object will have exact copy of all the fields of original object. If original object has any references to other objects as fields, then only references of those objects are copied into clone object, copy of those objects are not created. That means any changes made to those objects through clone object will be reflected in original object or vice-versa. Shallow copy is not 100% disjoint from original object. Shallow copy is not 100% independent of original object.

实验验证

package org.copy;/***浅拷贝 */class Family implements Cloneable {	private String name;	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	@Override	protected Object clone() throws CloneNotSupportedException {		return super.clone();	}}class Student implements Cloneable {	private String name;	private Family family;	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public Family getFamily() {		return family;	}	public void setFamily(Family family) {		this.family = family;	}	@Override	protected Object clone() throws CloneNotSupportedException {/*																 * The class																 * Object does																 * not itself																 * implement the																 * interface																 * Cloneable, so																 * calling the																 * clone method																 * on an object																 * whose class																 * is Object																 * will result																 * in throwing																 * an exception																 * at run time																 */		return super.clone();	}}class StringObj implements Cloneable {	private String name;	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	protected Object clone() throws CloneNotSupportedException {		return super.clone();	}}public class CopyT {	public static void main(String[] args) throws CloneNotSupportedException {		Family family = new Family();		family.setName("Army-Family");		Student student1 = new Student();		student1.setFamily(family);		student1.setName("James");		System.out.println(student1.getName() + " "				+ student1.getFamily().getName());		// OBJECT对象的clone()方法默认是浅拷贝,即只是拷贝了对象的引用,因此两者会同时改变		//A shallow copy just copies the values of the references in the class		Student student2 = (Student) student1.clone();		System.out.println(student2.getName() + " "				+ student2.getFamily().getName());		/*System.out.println((student1.getName()==student2.getName()));		System.out.println((student1.getFamily()==student2.getFamily()));*/		student2.setName("John");		student2.getFamily().setName("Agriculture-Family");		System.out.println(student1.getName() + " "				+ student1.getFamily().getName());		System.out.println(student2.getName() + " "				+ student2.getFamily().getName());				StringObj a = new StringObj();		a.setName("Hello");		StringObj b = (StringObj) a.clone();		System.out.println((a.getName()==b.getName()));		System.out.println(a.getName());		System.out.println(b.getName());		b.setName("I like you");		System.out.println(a.getName());		System.out.println(b.getName());		/*		 * If a change is made to the value of a deeply copied reference, then		 * the copy does not reflect that change because it does not share the		 * same reference.		 */			}}

实验结果

James Army-Family

James Agriculture-Family

John Agriculture-Family

true

Hello

Hello

Hello

I like you


通过实验结果,可以看到,String类型的数据相当于被“深拷贝”了,original对象和new copied对象相对独立,所以对后者的改变不会影响前者。在这一点上,浅拷贝和深拷贝是一致的,即它们都是相对独立的两个个体,即使它们存在拷贝与被拷贝的关系。

然而Family类型的数据则可以明显看到是被“深拷贝”了,original对象和new copied对象不独立,对后者的改变促使前者也改变,这是因为两者共同使用同一块索引。证明了Object.clone()的本质是进行浅拷贝。

什么是深拷贝?

深拷贝只是比浅拷贝更加彻底,使得original对象和new copied对象完全独立。代码实现上就需要我们将clone()方法进行一定的修改。之前只是拷贝了内部对象的引用,现在则写一个新的clone()方法,让它做一件事,那就是重新开辟一段空间,再将拷贝的数据放到这个新的对象之中。复制的动作是一样的,只是在此基础上多了一个动作,那就是开辟新的存储空间。因此只需要修改原始类(Student)的clone方法如下。

Deep copy of an object will have exact copy of all the fields of original object just like shallow copy. But in additional, if original object has any references to other objects as fields, then copy of those objects are also created by calling clone() method on them. That means clone object and original object will be 100% disjoint. They will be 100% independent of each other. Any changes made to clone object will not be reflected in original object or vice-versa.

protected Object clone() throws CloneNotSupportedException {/*																 * The class																 * Object does																 * not itself																 * implement the																 * interface																 * Cloneable, so																 * calling the																 * clone method																 * on an object																 * whose class																 * is Object																 * will result																 * in throwing																 * an exception																 * at run time																 */		Student student=(Student)super.clone();		student.family=(Family)family.clone();		return student;			}

实验结果

James Army-Family

James Army-Family

John Agriculture-Family

可见二者是完全独立的,是真正意义上的拷贝。即所谓深拷贝。

转载于:https://my.oschina.net/donngchao/blog/631403

你可能感兴趣的文章
策略模式
查看>>
我自研主动型氢原子钟将现身空间站
查看>>
maven添加本地jar包
查看>>
PHP 重置数组为连续数字索引的方式
查看>>
致创业者:APP已死 服务永生
查看>>
解决TIME_WAIT过多造成的问题
查看>>
mysql 主从同步故障解决 Error 'Row size too large (> 8126).
查看>>
16位纯数字MD5
查看>>
腾讯面试
查看>>
数据备份就用多备份
查看>>
企业如何进行IT基础设施规划
查看>>
我的友情链接
查看>>
iOS面试题第一波
查看>>
在centos中安装puppet和安装过程的一些错误解决
查看>>
html元素
查看>>
使用kaptcha生成验证码
查看>>
Maven学习总结(四)——Maven核心概念
查看>>
python 连接mongodb ,并将EXCEL文档导入mongodb
查看>>
第三节 在shell脚本中进行for循环
查看>>
Java Script 中定义对象的几种方式
查看>>