Java--浅拷贝和深拷贝的快速理解及实现方式介绍

我们在平时的开发中难免会遇到对象的复制问题。对于一些定义简单的对象(所有属性都为基本类型),如果直接赋值操作,相当于两个对象共用一个地址。修改其中那个对象的属性值,另一个的属性值也会一起变化。如果我们想让它们两个各自分配空间,就需要用到对象的拷贝。对于对象中只有基本类型属性的对象我们可以使用浅拷贝。

浅拷贝实现方式:

首先让定义的实体类实现Cloneable接口。然后重写clone方法,将clone方法的修饰符由protected改为public。这样就可以通过调用clone方法进行浅拷贝。

实现代码及测试如下:

public class Man implements Cloneable {
	private String name;
	private String sex;
	private int old;

	public Man(String name, String sex, int old) {
		super();
		this.name = name;
		this.sex = sex;
		this.old = old;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getOld() {
		return old;
	}

	public void setOld(int old) {
		this.old = old;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public String toString() {
		return "Man [name=" + name + ", sex=" + sex + ", old=" + old + "]";
	}

	public static void main(String[] args) throws CloneNotSupportedException {
		Man m1 = new Man("张三", "男", 25);
		Man m2 = (Man) m1.clone();
		m1.setName("李四");//修改对象1的值看两个对象值得变化情况
		System.out.println(m1.toString());
		System.out.println(m2.toString());
		m2.setSex("女");//修改对象2的值看两个对象值得变化情况
		System.out.println(m1.toString());
		System.out.println(m2.toString());
	}

}

执行结果如图:

Java--浅拷贝和深拷贝的快速理解及实现方式介绍_第1张图片

但是包含引用类型属性的对象a在赋值给b后,如果修改对象a中的引用类型属性,b中的该属性也会发生变化。这样的复制是不合逻辑的。我们希望a和b对象是相互独立的,修改其中一个的属性不会影响另一个的属性。这就要用到深拷贝了。

浅拷贝无法解决引用属性的赋值问题。如下图代码所示:


class Children {
	private String name;
	private String sex;
	int old;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getOld() {
		return old;
	}

	public void setOld(int old) {
		this.old = old;
	}

	public Children(String name, String sex, int old) {
		super();
		this.name = name;
		this.sex = sex;
		this.old = old;
	}

	@Override
	public String toString() {
		return "Children [name=" + name + ", sex=" + sex + ", old=" + old + "]";
	}

}

public class Man implements Cloneable {
	private String name;
	private String sex;
	private int old;
	private Children ch;

	public Man(String name, String sex, int old, Children ch) {
		super();
		this.name = name;
		this.sex = sex;
		this.old = old;
		this.ch = ch;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getOld() {
		return old;
	}

	public void setOld(int old) {
		this.old = old;
	}

	public Children getCh() {
		return ch;
	}

	public void setCh(Children ch) {
		this.ch = ch;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public String toString() {// 将chlidren对象内部属性打印
		return "Man [name=" + name + ", sex=" + sex + ", old=" + old + ", ch=" + ch.toString() + "]";
	}

	public static void main(String[] args) throws CloneNotSupportedException {
		Man m1 = new Man("张三", "男", 25, new Children("张小宝", "男", 5));
		Man m2 = (Man) m1.clone();
		Children ch = m1.getCh();
		ch.setName("王小丫");
		ch.setSex("女");
		System.out.println(m1.toString());
		System.out.println(m2.toString());
		ch = m2.getCh();
		ch.setName("张小柱");
		ch.setSex("男");
		System.out.println(m1.toString());
		System.out.println(m2.toString());
	}

}

执行结果如图:

Java--浅拷贝和深拷贝的快速理解及实现方式介绍_第2张图片

深拷贝实现方式:

首先是将引用的实体类也实现Cloneable接口(同时重写clone方法,也是修改修饰符为public)。然后同样是让定义的实体类实现Cloneable接口。然后重写clone方法,将clone方法的修饰符由protected改为public。但是方法体需要进行重写,将引用的对象属性调用它本身的clone方法进行赋值,然后将赋值后的对象返回即可。

具体代码如下(结合上一段代码):

@Override
	public Object clone() throws CloneNotSupportedException {
		Man man = (Man) super.clone();
		man.setCh((Children) man.getCh().clone());
		return man;
	}

写完深拷贝的代码再次运行。结果如下:

Java--浅拷贝和深拷贝的快速理解及实现方式介绍_第3张图片

这次两个对象就是完全独立,属性之间不存在共用同一个地址的情况了。

 

 

 

喜欢的朋友点个赞哦~~

你可能感兴趣的:(Java)