原型模式

来源:互联网 发布:胜科金仕达 待遇知乎 编辑:程序博客网 时间:2024/06/05 23:31

原型模式概念

  该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。java中复制通过clone()实现的。clone中涉及深、浅复制。深、浅复制的概念如下:

  ⑴浅复制(浅克隆) 

      被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址

  ⑵深复制(深克隆) 

      被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。 


public class Prototype {    public static void main(String[] args) throws CloneNotSupportedException {        //浅复制复制        Address address=new Address("jx","gz");        Programmer a=new Programmer("liaowp",address);        a.setAddress(new Address("jx", "gz"));        a.setName("liaowp");        Programmer b=(Programmer) a.clone();        b.setName("pwl");        b.getAddress().setProvince("bj");        System.err.println(b.getName()+b.getAddress().getProvince());        System.err.println(a.getName()+a.getAddress().getProvince());    }}class Programmer implements Cloneable{    private String name;    private Address address;    public Programmer(String name, Address address) {        this.name = name;        this.address = address;    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    protected Programmer clone() throws CloneNotSupportedException {        return (Programmer)super.clone();    }}class Address {    private String province;    private String city;    public Address(String province, String city) {        this.province = province;        this.city = city;    }    public String getProvince() {        return province;    }    public void setProvince(String province) {        this.province = province;    }    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }}

输出结果:pwlbj

                   liaowpbj

  可以看出来对象并复制,依然使用的是同一个引用。其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址。下面看深复制的写法,深复制有2种写法,一种是对象实现Cloneable,另外一种是二进制流。我都一起写了。

class Programmer implements Cloneable{    private String name;    private Address address;    public Programmer(String name, Address address) {        this.name = name;        this.address = address;    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    protected Programmer clone() throws CloneNotSupportedException {        Programmer programmer=(Programmer)super.clone();        programmer.setAddress(address.clone());        return programmer;    }}class Address implements Cloneable {    private String province;    private String city;    @Override    protected Address clone() throws CloneNotSupportedException {        return (Address) super.clone();    }    public Address(String province, String city) {        this.province = province;        this.city = city;    }    public String getProvince() {        return province;    }    public void setProvince(String province) {        this.province = province;    }    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }}

public Object deepClone(Object object) throws IOException, ClassNotFoundException {    ByteArrayOutputStream bos = new ByteArrayOutputStream();    ObjectOutputStream oss=new ObjectOutputStream(bos);    oss.writeObject(object);    ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());    ObjectInputStream ois=new ObjectInputStream(bis);    return ois.readObject();}


拷贝还有2个知识点,对象拷贝时,类的构造函数是不会被执行的。一个实现了 Cloneable 并重写了 clone 方法的类 Programmer,有一个无参构造或有参构造 ,通过 new 关键字产生了一个对象 A,再然后通过 A.clone()方式产生了一个新的对象 T,那么在对象拷贝时构造函数是不会被执行的。即拷贝的过程中只执行一次构造方法。

  Clone 与 final 两对冤家。对象的 clone 与对象内的 final 属性是由冲突.在上面的Programmer类中修改为private final Address address;去掉get,set方法, proto.address=(Address) address.clone();这一句就会报错: proto.address=(Address) address.clone();final类型不能重新设置值。解决办法就是删除掉fina咯

  深拷贝和浅拷贝建议不要混合使用,一个类中某些引用使用深拷贝某些引用使用浅拷贝,这是一种非常差的设计,特别是是在涉及到类的继承,父类有几个引用的情况就非常的复杂,建议深拷贝和浅拷贝分开实现。





阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 复合铝箔纸 铝箔纸 厂家 防静电铝箔袋 铝箔纸耐高温吗 保温棉铝箔纸 铝箔纸保温棉 铝箔纸分切机 铝箔纸屏蔽 铝箔纸压花机 保温用铝箔纸 铝箔纸加热有毒吗 铝罐厂家 铝管 铝方管重量计算公式 100x100铝方管 铝管价格 空调铝管多少钱一米 铝管多少钱一米 铝管加工 6063铝管 2a12铝管 铝管规格 铝管加工工艺 铝管批发 无缝铝管生产厂家 6061 铝管 铝管厂 无缝铝管批发 铝管6063 ly12厚壁铝管 口红铝管 6061铝管厂家 铝管铝棒 铝管供应商 防锈铝管 5052无缝铝管 2a11铝管 铝管加热 铝管安装 3a21铝管 铝管型号