一、浅克隆与深克隆
浅克隆克隆对象本身,包括基本数据类型变量和持有的非基本数据类型的引用类型变量,但不克隆非基本数据类型的引用类型变量所指向的对象
深克隆克隆对象本身,包括基本数据类型变量和持有的非基本数据类型的引用类型变量,以及克隆非基本数据类型的引用类型变量所指向的对象
如下图示:(有空再画)
二、代码
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对象同理。
三、相关设计模式
来源:CSDN
作者:weixin_42053328
链接:https://blog.csdn.net/weixin_42053328/article/details/101296465