使用场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑用原型模式拷贝多个对象供调用者使用。即保护性拷贝。
浅拷贝和深拷贝
在clone()方法中把对象的属性也进行拷贝的是深拷贝,如下文代码中的
student.hobbyList = (ArrayList<String>) this.hobbyList.clone();
只是把原对象的值付给拷贝对象的是浅拷贝
Student student = (Student) super.clone();
student.name = this.name;
但是虽然这里的name是浅拷贝。但是拷贝后的student的name属性和原来student的name属性并不会相互影响。
public class Student implements Cloneable {
String name;
ArrayList<String> hobbyList = new ArrayList<String>();
public Student() {
}
private void addHobby(String hobby) {
hobbyList.add(hobby);
}
@Override
protected Object clone() {
try {
Student student = (Student) super.clone();
student.name = this.name;
student.hobbyList = (ArrayList<String>) this.hobbyList.clone();
return student;
} catch (Exception e) {
}
return null;
}
public static void main(String[] args) {
Student student = new Student();
student.name = "张三";
student.addHobby("唱歌");
student.addHobby("跳舞");
student.addHobby("打游戏");
Student cloneStudent = (Student) student.clone();
System.out.println("原来的名字:" + student.name);
System.out.println("克隆的名字:" + cloneStudent.name);
for (String str : student.hobbyList) {
System.out.println("原来的爱好:" + str);
}
for (String str : cloneStudent.hobbyList) {
System.out.println("克隆的爱好:" + str);
}
cloneStudent.name = "李四";
cloneStudent.addHobby("看书");
System.out.println("修改克隆的属性后================");
System.out.println("原来的名字:" + student.name);
System.out.println("克隆的名字:" + cloneStudent.name);
for (String str : student.hobbyList) {
System.out.println("原来的爱好:" + str);
}
for (String str : cloneStudent.hobbyList) {
System.out.println("克隆的爱好:" + str);
}
}
}
打印结果
原来的名字:张三
克隆的名字:张三
原来的爱好:唱歌
原来的爱好:跳舞
原来的爱好:打游戏
克隆的爱好:唱歌
克隆的爱好:跳舞
克隆的爱好:打游戏
修改克隆的属性后================
原来的名字:张三
克隆的名字:李四
原来的爱好:唱歌
原来的爱好:跳舞
原来的爱好:打游戏
克隆的爱好:唱歌
克隆的爱好:跳舞
克隆的爱好:打游戏
克隆的爱好:看书