浅克隆与深克隆

落花浮王杯 提交于 2019-12-07 22:56:35

一、浅克隆与深克隆

浅克隆克隆对象本身,包括基本数据类型变量和持有的非基本数据类型的引用类型变量,但不克隆非基本数据类型的引用类型变量所指向的对象
深克隆克隆对象本身,包括基本数据类型变量和持有的非基本数据类型的引用类型变量,以及克隆非基本数据类型的引用类型变量所指向的对象

如下图示:(有空再画)

二、代码

Person类持有Job类的引用,Job类持有Salary类的引用。Client类做测试。
1、浅克隆
Person.java

package com.test.clone;

import java.util.Date;

public class Person implements Cloneable{
	
	private String name;
	
	private Job job;
	
	private Date date;
	
	public Person(String name, Job job) {
		super();
		this.name = name;
		this.job = job;
	}
	
	public Person(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Person clone = (Person)super.clone();
		return clone;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", job=" + job + ", date=" + date + "]";
	}
}

Job.java

package com.test.clone;

public class Job{

	private String name;
	
	private Salary salary;

	public String getName() {
		return name;
	}

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

	public Salary getSalary() {
		return salary;
	}

	public void setSalary(Salary salary) {
		this.salary = salary;
	}

	public Job(String name) {
		super();
		this.name = name;
	}
	
	public Job(String name, Salary salary) {
		super();
		this.name = name;
		this.salary = salary;
	}
	public Job() {
		super();
	}

	@Override
	public String toString() {
		return "Job [name=" + name + ", salary=" + salary + "]";
	}
	
}

Salary.java

package com.test.clone;

public class Salary{
	
	private int money;

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}

	public Salary(int money) {
		super();
		this.money = money;
	}

	@Override
	public String toString() {
		return "Salary [money=" + money + "]";
	}
}

Client测试类

package com.test.clone;

import java.util.Date;

public class Client {
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Person person = new Person("lucy",new Job("java", new Salary(100)));
		person.setDate(new Date());
		
		Person clone = (Person)person.clone();
		
		clone.setName("lily");
		clone.getJob().setName("python");
		clone.getJob().getSalary().setMoney(1000);
		clone.setDate(new Date(10000L));
		
		System.out.println(person);
		System.out.println(clone);
	}

}

控制台打印的测试结果:

Person [name=lucy, job=Job [name=python, salary=Salary [money=1000]], date=Tue Sep 24 17:27:56 CST 2019]
Person [name=lily, job=Job [name=python, salary=Salary [money=1000]], date=Thu Jan 01 08:00:10 CST 1970]

可以看出,修改克隆对象clone的job信息和salary信息时,原来的对象person也发生了改变,上述结果中的斜体字。因为原来的对象和克隆的对象所持有的Job的对象引用指向堆内存中的同一个对象。Salary对象同理。
2、深克隆
Person.java

package com.test.clone;

import java.util.Date;

public class Person implements Cloneable{
	
	private String name;
	
	private Job job;
	
	private Date date;
	
	public Person(String name, Job job) {
		super();
		this.name = name;
		this.job = job;
	}
	
	public Person(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Person clone = (Person)super.clone();
		//关键代码
		clone.setJob((Job)clone.getJob().clone());
		return clone;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", job=" + job + ", date=" + date + "]";
	}

}

Job.java

package com.test.clone;

public class Job implements Cloneable{

	private String name;
	
	private Salary salary;

	public String getName() {
		return name;
	}

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

	public Salary getSalary() {
		return salary;
	}

	public void setSalary(Salary salary) {
		this.salary = salary;
	}

	public Job(String name) {
		super();
		this.name = name;
	}
	
	public Job(String name, Salary salary) {
		super();
		this.name = name;
		this.salary = salary;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		Job clone = (Job)super.clone();
		//关键代码
		clone.setSalary((Salary)clone.getSalary().clone());
		return clone;
	}

	public Job() {
		super();
	}

	@Override
	public String toString() {
		return "Job [name=" + name + ", salary=" + salary + "]";
	}
	
}

Salary.java

package com.test.clone;

public class Salary implements Cloneable{
	
	private int money;

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}

	public Salary(int money) {
		super();
		this.money = money;
	}

	@Override
	public String toString() {
		return "Salary [money=" + money + "]";
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		//关键代码
		return super.clone();
	}
}

Client测试类

package com.test.clone;

import java.util.Date;

public class Client {
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Person person = new Person("lucy",new Job("java", new Salary(100)));
		person.setDate(new Date());
		
		Person clone = (Person)person.clone();
		
		clone.setName("lily");
		clone.getJob().setName("python");
		clone.getJob().getSalary().setMoney(1000);
		clone.setDate(new Date(10000L));
		
		
		System.out.println(person);
		System.out.println(clone);
	}

}

控制台打印的测试结果:

Person [name=lucy, job=Job [name=java, salary=Salary [money=100]], date=Tue Sep 24 17:36:42 CST 2019]
Person [name=lily, job=Job [name=python, salary=Salary [money=1000]], date=Thu Jan 01 08:00:10 CST 1970]

可以看出,修改克隆对象clone的job信息和salary信息时,原来的对象person没有发生改变,上述结果中的斜体字。因为原来的对象和克隆的对象所持有的Job的对象引用指向堆内存中不同的对象。Salary对象同理。

三、相关设计模式

原型模式

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!