本文是自己的学习笔记,主要参考以下资料
- 大话设计模式,程杰著,清华大学出版社出版
- 马士兵教育
1、Java中的原型模式
原型模式是用在需要用到多个属性类型完全一样的对象的场景,简单来说就是能简单地复制一个对象。
1.1、深拷贝和浅拷贝
Java中自带的原型模式是clone()
方法。该方法是Object
的方法,native
类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。
我们写简单类的时候只需要实现Cloneable
接口,然后调用Object::clone
方法就可实现克隆功能。这样实现的方式是浅拷贝。
clone
是完全复制对象的信息,如果一个对象里的成员变量的类型不是基础类型,是其他复杂类,那关于这个成员变量,对象里存储的信息不是成员变量的一整个对象而是关于成员变量对象的引用,是地址信息。clone
产生的新对象自然也是记录地址信息。那么两个新对象的关于成员变量的信息就会指向同一个对象。
比如下面的一个类有三个成员变量,前两个是的类型分别是int
和String
,而最后一个类型是File
。源对象和克隆出来的对象的第三个成员变量都指向同一个File
对象。
1.2、浅拷贝实现
比如我们写一个Person类实现一下clone功能。
public class Person implements Cloneable{
public Integer age;
public String name;
public Location location;
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
public class Location {
public String address;
public Integer no;
}
这样就算是实现了Person
的浅拷贝,可以看看下面的验证代码。
Location location1 = new Location("address1", 1);
Person person1 = new Person(1, "name1", location1);
Person person2 = (Person) person1.clone();
System.out.println(person2 == person1);
System.out.println(person1.toString());
System.out.println(person2.toString());
System.out.println(person1.location == person2.location);
输出如下,可以看到两个对象的location
都指向了同一个对象。
1.3、深拷贝实现
实现深拷贝也不是什么复杂的事情,就是手动再克隆成员变量然后赋值给新的克隆对象。
和上面同样的代码,唯一的不同是Person::clone
和Location
也实现Cloneable
接口。
public class Person implements Cloneable{
public Integer age;
public String name;
public Location location;
@Override
public Object clone() throws CloneNotSupportedException{
Person person = (Person) super.clone();
person.setLocation((Location) ![请添加图片描述](https://img-blog.csdnimg.cn/b0977dd2f8a045f8a949033979f14c56.png)
person.getLocation().clone());
return person;
}
}
public class Location implements Cloneable{
public String address;
public Integer no;
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
可以看到,两个对象的Location指向了不用的对象。