Java设计模式【之】原型模式-浅拷贝【场景:克隆羊】

1.原型模式(Prototype)

  • 实现方式:

  • 需要被克隆的class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 CloneNotSupportedException)

  • 注意:
    1.被克隆对象.clone()出的对象,是被克隆对象的当前状态。
    2.被克隆对象 如果使用的是默认实现 super.clone(); 此时属于浅拷贝。

  • 特点
    1.创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
    2.不用重新初始化对象,而是动态地获得对象运行时的状态。
    3.在实现深克隆的时候可能需要比较复杂的代码。
    4.实现深拷贝是,推荐序列化方式。

浅拷贝

  • 浅拷贝
  • 1.成员变量是,基本数据类型,此时浅拷贝是值传递。
    其中一个对象的值修改后,不会影响到另一个对象的值。
  • 2.成员变量是,引用数据类型,比如:数组、类的对象。
    此时浅拷贝是引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。
    两个对象中的该成员变量执行的是同一个地址,其中一个对象的值修改后,另一个对象的值也会改变。

深拷贝

  • 深拷贝
  • 1.复制对象的所有基本数据类型的成员变量值
  • 2.为所有引用数据类型的成员变量申请存储空间,直到该对象可达的所有对象,递归式完全克隆
  • 3.深拷贝实现方式
    1.重写clone方法来实现深拷贝
    2.通过对象序列化实现深拷贝(推荐)

2.代码实现(浅拷贝)

2.1.羊.class


public class Yang_implements Cloneable {
    public String name;
    public int age;
    public ArrayList<String> list;

    public Yang_(String name, int age) {
        this.name = name;
        this.age = age;
        this.list = new ArrayList<>();
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void add() {
        this.list.add(" MMM ");

    }

}

2.2.测试类.class

  • 注意控制台输出在这里插入代码片内容:浅拷贝导致,虽然只是更改了其中一只羊的数组,但是两只羊的数组内容都发生了变化

/**
 * 原型模式(Prototype)
 * 实现方式:
 * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 CloneNotSupportedException)
 * 注意:
 * 1.被克隆对象.clone()出的对象,是被克隆对象的当前状态
 * 2.被克隆对象 如果返回的值是 super.clone(); 此时属于浅拷贝
 * <p>
 * 浅拷贝
 * 1)成员变量是,基本数据类型,此时浅拷贝是值传递。其中一个对象的值修改后,不会影响到另一个对象的值。
 * 2)成员变量是,引用数据类型,比如:数组、类的对象。此时浅拷贝是引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。两个对象中的该成员变量执行的是同一个地址,其中一个对象的值修改后,另一个对象的值也会改变。
 */
public class _Test_浅 {

    public static void main(String[] args) throws CloneNotSupportedException {

        //
        Yang_浅 yang = new Yang_("001", 1);
        System.out.println("原始羊-姓名:" + yang.name);
        System.out.println("原始羊-地址:" + yang);
        System.out.println();

        //
        Yang_浅 clone_yang = (Yang_) yang.clone();
        System.out.println("克隆羊-地址:" + clone_yang);
        System.out.println("克隆羊-姓名:" + clone_yang.name);
        System.out.println();

        //
        System.out.println("修改原始羊姓名为:小明");
        yang.setName("小明");
        System.out.println();

        //
        System.out.println("原始羊-姓名:" + yang.name);
        System.out.println("克隆羊-姓名:" + clone_yang.name);
        System.out.println();

        //
        System.out.println("原始羊-数组内容:" + yang.list);
        System.out.println("克隆羊-数组内容:" + clone_yang.list);
        System.out.println();

        //
        System.out.println("原始羊数组添加内容 MMM ");
        yang.add();
        System.out.println();

        //
        System.out.println("原始羊-数组内容:" + yang.list);
        System.out.println("克隆羊-数组内容:" + clone_yang.list);
        System.out.println();


    }

}

2.3.输出内容

原始羊-姓名:001
原始羊-地址:com.sjms._04_原型.Yang_浅@4d7e1886

克隆羊-地址:com.sjms._04_原型.Yang_浅@3cd1a2f1
克隆羊-姓名:001

修改原始羊姓名为:小明

原始羊-姓名:小明
克隆羊-姓名:001

原始羊-数组内容:[]
克隆羊-数组内容:[]

原始羊数组添加内容 MMM 

原始羊-数组内容:[ MMM ]
克隆羊-数组内容:[ MMM ]

3.源码下载

《七大设计原则》

《目录:Java设计模式》

《幕》

  • 《清平调—李白》
  • 云想衣裳花想容,春风拂面露华浓。
  • 若非群玉山头见,会向瑶台月下逢。
  • ~ 今 ~ ❀ ~ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀❀❀❀ ❀❀❀❀❀❀❀
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长毛山顶洞人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值