23种设计模式中的原型模式
2017-08-09 16:02 猪牙哥 阅读(182) 评论(0) 编辑 收藏 举报原型模式:通过复制现有实例来创建新的实例,无须知道相应类的信息。
个人见解:在大量循环时,需要初始化对象,用 原型模式能节省大量的初始化所花费的时间,值得一谈的是浅复制和深复制
浅复制:Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝
代码
在这里我定义了一个学生类Student.java
public class Student implements Cloneable { private String name; public Student(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } }
还有一个Teacher.java
public class Teacher implements Cloneable { private String name; private Student[] students; public Teacher(String name, Student... students) { super(); this.name = name; this.students = students; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student[] getStudents() { return students; } public void setStudents(Student[] students) { this.students = students; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } }
然后测试
public static void main(String[] args) throws CloneNotSupportedException { Teacher t=new Teacher("李老师", new Student("小明"),new Student("小红")); System.out.println(t); System.out.println(t.getStudents()); System.out.println(Arrays.toString(t.getStudents())); System.out.println("-------------------------------------------------"); Teacher teacher = (Teacher) t.clone(); System.out.println(teacher); System.out.println(teacher.getStudents()); System.out.println(Arrays.toString(teacher.getStudents())); }
输出结果
可以看到拷贝出来的对象跟被拷贝的对象内存地址不一样,也就是不同的对象,但是指向的Student数组的内存地址是一样的,那就是说改变拷贝出来的对象中的Student数组会影响被拷贝的对象中的Student数组,这个在开发中很明显不是我们想要的,那么我们看一下深复制。
深复制:要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝
实例代码,
只需要改动Teacher.java
public class Teacher implements Cloneable { private String name; private Student[] students; public Teacher(String name, Student... students) { super(); this.name = name; this.students = students; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student[] getStudents() { return students; } public void setStudents(Student[] students) { this.students = students; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Teacher clone = null; clone = (Teacher) super.clone(); clone.students = this.students.clone(); return clone; } }
输出结果
很明显,指向Student数组都不一样,那么就是连Student数组也拷贝了
大家有没有发现,为什么Student数组里面的字符串地址都是一样?这实际上是Java虚拟机对字符串的一种优化,并不在本章节的讨论范围内,大家有兴趣可以去了解下。