1.使用场景:
- 类初始化需要消化非常多的资源, 这个资源包括数据, 硬件资源等,通过原型拷贝避免这些消耗;
- 通过new产生一个对象需要非常繁琐的数据准备或访问权限, 这时可以考虑使用原型模式;
- 一个对象需要提供给其他对象访问, 而且各个调用者可能都需要修改其值时, 可以考虑用原型模式拷贝多个对象供调用者使用, 即保护性拷贝;
2.需求:
复制老对象的所有属性给一个新对象, 并修改新对象中的值, 而且不能影响到老对象的属性;如果没有原型模式, 操作起来还是挺复杂的.
3.深拷贝与浅拷贝:
public class Person implements Cloneable {
public String mName;
public int mAge;
public String mSex;
public float mSalary;
public ArrayList<String> mFavorite = new ArrayList<String>();
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public int getAge() {
return mAge;
}
public void setAge(int age) {
mAge = age;
}
public String getSex() {
return mSex;
}
public void setSex(String sex) {
mSex = sex;
}
public float getSalary() {
return mSalary;
}
public void setSalary(float salary) {
mSalary = salary;
}
public void setFavorite(String favorite) {
mFavorite.add(favorite);
}
public ArrayList<String> getFavorite() {
return mFavorite;
}
@SuppressWarnings("unchecked")
@Override
protected Person clone() throws CloneNotSupportedException {
try {
Person person = (Person) super.clone();
//下面代码注释掉是浅拷贝, 加上则是深拷贝;
person.mFavorite = (ArrayList<String>) mFvorite.clone();
return person;
} catch (Exception e) {
}
return null;
}
public void showPersonID() {
System.out.println("Person->name:" + mName + ",age:" + mAge + ",sex:"
+ mSex + ",salary:" + mSalary);
System.out.println("Favorite:");
for (String favorite : mFavorite) {
System.out.println("favorite:" + favorite);
}
}
}
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person();
person1.setName("name1");
person1.setAge(1);
person1.setSex("sex1");
person1.setSalary(1);
person1.setFavorite("吃");
person1.setFavorite("喝");
person1.showPersonID();
Person person2 = person1.clone();
person2.showPersonID();
person2.setName("name2");
person2.setAge(2);
person2.setSex("sex2");
person2.setSalary(2);
person2.setFavorite("跳");
person2.showPersonID();
person1.showPersonID();
}
}
注意, 浅拷贝容易出问题, 因为person2.setFavorite(“跳”)影响到了person的mFavorite属性.所以在实际开发中需要深拷贝,
下图是浅拷贝的打印结果:
下图是深拷贝的打印结果:
深拷贝与浅拷贝的区别, 现在仅仅记下来结论:
clone方法仅仅进行了浅拷贝, person2的mFavorite只是单纯的指向了this.mFavorite, 并没有重新创建一个对象, 此时他俩指向内存中的同一块区域, 所以修改person1或person2的mFavorite会相互影响;