原型模式学习--浅拷贝&深拷贝

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中的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值