用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
原型模式就是从一个对象在创建另外一个可定制的对象,而且不需要知道任何创建的细节。
说通俗点就是通过现有类的一个对象来拷贝一个它的副本来生成新的对象。
拷贝分为浅拷贝和深拷贝。
浅拷贝:值传递的字段会被复制,而引用传递的字段则不会复制。
深拷贝:值传递的字段和引用传递的字段都会被复制。
class Major{
private String majorName;
public Major(String majorName) {
this.majorName = majorName;
}
public String getMajorName() {
return majorName;
}
public void setMajorName(String majorName) {
this.majorName = majorName;
}
}
//拷贝对象
class Student implements Cloneable{
private String name;//值传递字段可以被复制
private int age;//值传递字段可以被复制
private Major major;//引用传递字段不能被复制
public Student(String name, int age, Major major) {
this.name = name;
this.age = age;
this.major = major;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Major getMajor() {
return major;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMajor(Major major) {
this.major = major;
}
/*
Java中想实现浅拷贝,需要拷贝对象实现cloneable接口并重写clone()即可
*/
//浅拷贝
public Object clone() throws CloneNotSupportedException {
return super.clone();//调用Object的clone()来实现浅拷贝
}
}
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Major major = new Major("Java技术应用方向");
Student student1 = new Student("xxgbl", 22, major);
//浅拷贝
Student student2 = (Student) student1.clone();
System.out.println(student1 == student2);
System.out.println(student1.getName() + " " +student1.getAge()+" "+student1.getMajor().getMajorName());
System.out.println(student2.getName() + " " +student2.getAge()+" "+student2.getMajor().getMajorName());
student1.setAge(35);//值传递的子段被复制,student1的改动不会影响到student2
student1.getMajor().setMajorName("xxxxx");//引用传递的字段没有被复制,student1的改动会影响到student2
System.out.println(student1.getName() + " " +student1.getAge()+" "+student1.getMajor().getMajorName());
System.out.println(student2.getName() + " " +student2.getAge()+" "+student2.getMajor().getMajorName());
}
}
//结果
false //student1和student2指向的不是同一个对象了
xxgbl 22 Java技术应用方向
xxgbl 22 Java技术应用方向
xxgbl 35 xxxxx
xxgbl 22 xxxxx
Object的clone()默认是浅拷贝行为。即当你想拷贝Student对象的时候,此对象中的值传递字段会被复制一份,但引用传递的字段并不会被复制。
那么如何实现引用传递的字段也被复制呢?我想通过拷贝得到两个内容相同但又彼此独立的对象(任意一个对象修改引用传递的字段不会对另一个对象造成影响)
让引用传递的字段也能被拷贝,并且在顶层类(Student)的clone()中调用引用传递字段的clone()。
//让Major实现Cloneable接口并重写clone()
class Major implements Cloneable{
private String majorName;
public Major(String majorName) {
this.majorName = majorName;
}
public String getMajorName() {
return majorName;
}
public void setMajorName(String majorName) {
this.majorName = majorName;
}
protected Object clone()throws CloneNotSupportedException{
return super.clone();
}
}
class Student implements Cloneable{
private String name;
private int age;
private Major major;
public Student(String name, int age, Major major) {
this.name = name;
this.age = age;
this.major = major;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Major getMajor() {
return major;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMajor(Major major) {
this.major = major;
}
//深拷贝
protected Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();//通过浅拷贝得到拷贝后的Student对象
student.major = (Major) major.clone();//通过Student对象获得Magjor对象并调用Magjor对象的clone()得到拷贝后的Major对象
return student;
}
}
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Major major = new Major("Java技术应用方向");
Student student1 = new Student("xxgbl", 22, major);
//
Student student2 = (Student) student1.clone();
System.out.println(student1 == student2);
System.out.println(student1.getName() + " " +student1.getAge()+" "+student1.getMajor().getMajorName());
System.out.println(student2.getName() + " " +student2.getAge()+" "+student2.getMajor().getMajorName());
System.out.println();
student1.setAge(35);
student1.getMajor().setMajorName("xxxxx");//引用传递的字段被复制,student1的改动不会影响到student2
System.out.println(student1.getName() + " " +student1.getAge()+" "+student1.getMajor().getMajorName());
System.out.println(student2.getName() + " " +student2.getAge()+" "+student2.getMajor().getMajorName());
}
}
//结果
false
xxgbl 22 Java技术应用方向
xxgbl 22 Java技术应用方向
xxgbl 35 xxxxx
xxgbl 22 Java技术应用方向
原文:https://www.cnblogs.com/xxgbl/p/13742177.html