原型模式Prototype

5 篇文章 0 订阅
1 篇文章 0 订阅

概述

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象

场景

游戏存档
对于复杂对象,已存在一个实例时创建新的实例

实现

被克隆的类需要继承Cloneable接口并重写clone方法

浅克隆

/**
 * 被克隆对象
 */
public class BeCloneBean implements Cloneable{
    public String name;
    public String loc;
    public int age;
    public AnotherBean anotherBean;
    
    public BeCloneBean(String name, String loc, int age, AnotherBean anotherBean) {
        this.name = name;
        this.loc = loc;
        this.age = age;
        this.anotherBean = anotherBean;
    }
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "BeCloneBean{" +
                "name='" + name + '\'' +
                ", loc='" + loc + '\'' +
                ", age=" + age +
                ", anotherBean=" + anotherBean +
                '}';
    }
}
/**
 * 被克隆对象的一个成员
 */
public class AnotherBean {
    public String name;
    public int age;

    public AnotherBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
/**
  * 测试浅克隆
   * @throws CloneNotSupportedException
   */
  @Test
  public void testShallowClone() throws CloneNotSupportedException {
      AnotherBean anotherBean = new AnotherBean("weic",18);
      BeCloneBean beCloneBean = new BeCloneBean("weicheng","fujian",18,anotherBean);
      BeCloneBean clone = (BeCloneBean)beCloneBean.clone();
      System.out.println(beCloneBean == clone);
      System.out.println(beCloneBean.anotherBean == clone.anotherBean);
      System.out.println("------------------------------------------");
      System.out.println(beCloneBean.name == clone.name);
      beCloneBean.name="aaa";
      System.out.println(clone.name);
  }

浅克隆执行结果:
在这里插入图片描述

深克隆

/**
 * 被克隆对象
 */
public class BeCloneBean implements Cloneable{
    public String name;
    public String loc;
    public int age;
    public AnotherBean anotherBean;

    public BeCloneBean(String name, String loc, int age, AnotherBean anotherBean) {
        this.name = name;
        this.loc = loc;
        this.age = age;
        this.anotherBean = anotherBean;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        BeCloneBean clone =(BeCloneBean)super.clone();
        clone.anotherBean = (AnotherBean) clone.anotherBean.clone();
        return clone;
    }
    @Override
    public String toString() {
        return "BeCloneBean{" +
                "name='" + name + '\'' +
                ", loc='" + loc + '\'' +
                ", age=" + age +
                ", anotherBean=" + anotherBean +
                '}';
    }
}
/**
 * 被克隆对象的一个成员
 */
public class AnotherBean implements Cloneable {
    public String name;
    public int age;

    public AnotherBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
/**
  * 测试深度克隆
  * @throws CloneNotSupportedException 
  */
 @Test
 public void testDeepClone() throws CloneNotSupportedException {
     AnotherBean anotherBean = new AnotherBean("weic",18);
     BeCloneBean beCloneBean = new BeCloneBean("weicheng","fujian",18,anotherBean);
     BeCloneBean clone = (BeCloneBean)beCloneBean.clone();
     System.out.println(beCloneBean == clone);
     System.out.println("------------------------------------------");
     System.out.println(beCloneBean.anotherBean == clone.anotherBean);
 }

深克隆执行结果:
在这里插入图片描述

总结

1.浅克隆:只有被克隆的对象实现Cloneable接口重写clone方法,这种方式只能克隆基本类型数据,克隆前后引用型的属性还是指向同一个对象;
2.深克隆:被克隆对象及其内部其他对象类型都实现Cloneable接口,重写clone方法,这种方式克隆前后包括内部引用型属性都是不同的对象;
3.String类型说明:String类型被克隆后两个对象的String引用都指向字符串常量池的同一个常量,因此他们是同一个对象,但是当改变其中一个对象String的值的时候此String类型引用将指向另一个内存空间,因此不会影响其他的克隆对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值