原型模式

原形模式Prototype,指用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

基本思路是定义一个类,实现Cloneable接口,调用clone方法。

这就涉及到java中的深拷贝和浅拷贝。

Object类里的clone()方法仅仅用于浅拷贝(拷贝基本成员属性,对于引用类型仅返回指向改地址的引用)

public static void main(String[] args) throws CloneNotSupportedException {
        List<String> addr1 = new ArrayList<>();
        addr1.add("北京市朝阳区");
        addr1.add("北京市海淀区");
        Person p1 = new Person("张三",30, addr1);

        Person p2 = (Person) p1.clone();

        System.out.println("p1:" + p1.toString());  //p1:[张三,30,[北京市朝阳区, 北京市海淀区],]
        System.out.println("p2:" + p2.toString());  //p2:[张三,30,[北京市朝阳区, 北京市海淀区],]

        p1.setAge(50);
        p1.getHouseList().add("北京市通城区");

        System.out.println("p1:" + p1.toString());  //p1:[张三,50,[北京市朝阳区, 北京市海淀区, 北京市通城区],]
        System.out.println("p2:" + p2.toString());  //p2:[张三,30,[北京市朝阳区, 北京市海淀区, 北京市通城区],]

     //p2中clone方法已经把基本数据类型age的值拷贝完了,所以p1或p2的age再改变的时候,另外一个对象的age是不变的。
//但是list类型传的是引用,p1与p2的list是堆中的同一个对象 p2.setAge(70); p2.getHouseList().add("武汉市江汉区"); System.out.println("p1:" + p1.toString()); //p1:[张三,50,[北京市朝阳区, 北京市海淀区, 北京市通城区, 武汉市江汉区],] System.out.println("p2:" + p2.toString()); //p2:[张三,70,[北京市朝阳区, 北京市海淀区, 北京市通城区, 武汉市江汉区],] }

class Person implements Cloneable{
private String name;
private Integer age;
private List<String> houseList;
}
 

如果想要实现深拷贝,需要在Person类中重写clone方法,这样拷贝之后就不会出现p1与p2修改值后互相影响的现象。

class Person implements Cloneable{
    private String name;
    private Integer age;
    private ArrayList<String> houseList;

    public Person(String name, int age, ArrayList<String> houseList) 
   {
        this.name = name;
        this.age = age;
        this.houseList = houseList;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Person p = (Person) super.clone();
        p.houseList = (ArrayList<String>) houseList.clone();
        return p;
    }
}

 

上一篇:原型模式


下一篇:windows 凭据更改