1、原型模式:先创建一个原型对象实例A,然后通过拷贝实例A的方式创建对象实例BCD…
2、浅拷贝:
(1)对于基本数据类型和String类型的成员变量按照值传递
(2)对于引用数据类型的成员变量,如对象,按照引用传递
(3)实现方式有两种:
构造器:将B类引用以参数传入A类的构造器中
重写clone()方法:实现Cloneable接口,重写clone(),调用super.clone();
// 首先准备两个实体类,分别在两个实体类中重写clone方法
package 创建型模式.原型模式.浅拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:09
* @Description: 员工类
*/
public class Employee implements Cloneable {
private int id;
private String name;
private Salary salary;
public Employee(int id, String name, Salary salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Salary getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary.setSalary(salary);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
package 创建型模式.原型模式.浅拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:10
* @Description: 薪水
*/
public class Salary implements Cloneable {
private int salary;
public Salary(int salary) {
this.salary = salary;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary.setSalary(salary);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Salary{" +
"salary=" + salary +
'}';
}
}
// 测试类
package 创建型模式.原型模式.浅拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:09
* @Description: 浅拷贝
*/
public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Salary salary = new Salary(1000);
Employee e1 = new Employee(1, "张三", salary);
Employee e2 = (Employee) e1.clone();
System.out.println("e1 : " + e1);
System.out.println("e2 : " + e2);
System.out.println("e1.getSalary() == e2.getSalary() ==> " + (e1.getSalary() == e2.getSalary()));
e2.setName("李四");
e2.setSalary(2000);
e2.setId(3);
System.out.println("e2 : " + e2);
System.out.println("e1 : " + e1);
System.out.println("e1.getSalary() == e2.getSalary() ==> " + (e1.getSalary() == e2.getSalary()));
}
}
// 输出
/*
e1 : Employee{id=1, name='张三', salary=Salary{salary=1000}}
e2 : Employee{id=1, name='张三', salary=Salary{salary=1000}}
e1.getSalary() == e2.getSalary() ==> true
e2 : Employee{id=3, name='李四', salary=Salary{salary=2000}}
e1 : Employee{id=1, name='张三', salary=Salary{salary=2000}}
e1.getSalary() == e2.getSalary() ==> true
*/
根据输出结果显示:当实例e2改变了Employee的参数值时,由于id是基本数据类型的,name是String类型的,所以按照值传递拷贝,不会影响e1实例的值。但是由于salary是对象,会按照引用传递,输出:e1.getSalary() == e2.getSalary() ==> true
,也就是说e1.salary和e2.salary的地址是同一个,在e2中修改了salary的值后,e1的salary的值也变为了2000,所以在浅拷贝中改变引用数据类型的对象值会影响到其他对象中的值
3、深拷贝:
(1)复制基本数据类型和String类型的值
(2)为引用数据类型申请空间,复制引用数据类型的对象值,以及该对象引用的所有对象的值
// 首先准备两个实体类:重写clone方法
package 创建型模式.原型模式.深拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:09
* @Description: 员工类
*/
public class Employee implements Cloneable {
private int id;
private String name;
private Salary salary;
public Employee(int id, String name, Salary salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Salary getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary.setSalary(salary);
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = null;
// 浅拷贝:拷贝基本数据类型和引用数据类型指向的值
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
// 将Obj转换为Employee类型,然后更改对salary执行浅拷贝,拿到值并赋给e
Employee e = (Employee)obj;
e.salary = (Salary) e.getSalary().clone();
return obj;
}
}
package 创建型模式.原型模式.深拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:10
* @Description: 薪水
*/
public class Salary implements Cloneable {
private int salary;
public Salary(int salary) {
this.salary = salary;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = null;
// 浅拷贝:拷贝基本数据类型和String指向的值
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
@Override
public String toString() {
return "Salary{" +
"salary=" + salary +
'}';
}
}
package 创建型模式.原型模式.深拷贝;
/**
* @Author: lxpStu
* @Date: 2021/11/01/23:35
* @Description: 深拷贝
*/
public class DeepCopy implements Cloneable {
public static void main(String[] args) throws CloneNotSupportedException {
Salary salary = new Salary(1000);
Employee e1 = new Employee(1, "张三", salary);
Employee e2 = (Employee) e1.clone();
System.out.println("e1 : " + e1);
System.out.println("e2 : " + e2);
System.out.println("e1.getSalary() == e2.getSalary() ==> " + (e1.getSalary() == e2.getSalary()));
e2.setName("李四");
e2.setSalary(2000);
e2.setId(3);
System.out.println("e1 : " + e1);
System.out.println("e2 : " + e2);
System.out.println("e1.getSalary() == e2.getSalary() ==> " + (e1.getSalary() == e2.getSalary()));
}
}
// 输出:
/*
e1 : Employee{id=1, name='张三', salary=Salary{salary=1000}}
e2 : Employee{id=1, name='张三', salary=Salary{salary=1000}}
e1.getSalary() == e2.getSalary() ==> false
e1 : Employee{id=1, name='张三', salary=Salary{salary=1000}}
e2 : Employee{id=3, name='李四', salary=Salary{salary=2000}}
e1.getSalary() == e2.getSalary() ==> false
*/
可见修改基本数据类型的不会影响其他对象,根据e1.getSalary() == e2.getSalary() ==> false
可知,深拷贝对于引用数据类型来说地址值是不一样的,所以在e2中改变对象的值不会影响e1中的值