熊大
我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式来创建新对象,
以达到节省创建时间的目的。这种基于原型来创建对象的方式就叫作原型设计模式
原型模式是用拷贝来实现得,而拷贝又分深拷贝与浅拷贝。
引用拷贝:
public class Girl {
private Integer age;
private String sex;
private String name;
}
public static void main(String[] args) {
Girl girl=new Girl();
girl.setAge(18);
girl.setSex("女");
girl.setName("小艾");
Girl girl1=girl;
System.out.println(girl.hashCode());
System.out.println(girl1.hashCode());
}
输出结果:
2383061
2383061
上面看出两个对象同时指向同一个地址这也叫做引用拷贝。
浅拷贝:
浅拷贝我们只需要实现Cloneable改接口重写clone接口然后定义为publlic。
代码示例:
public class Girl implements Cloneable {
private Integer age;
private String sex;
private String name;
private Test test;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Data
public static class Test{
private String firstName;
}
}
public static void main(String[] args) throws Exception {
Girl girl = new Girl();
girl.setAge(18);
girl.setSex("女");
girl.setName("小");
Girl.Test test = new Girl.Test();
test.setFirstName("123");
girl.setTest(test);
// 拷贝girl 对象
Girl clone = (Girl) girl.clone();
// 修改test对象属性
test.setFirstName("234");
System.out.println("========clone" + clone);
System.out.println("=========girl" + girl);
}
结果输出:
cloneGirl(age=18,sex=女,name=小,test=Girl.Test(firstName=234))
girlGirl(age=18,sex=女,name=小,test=Girl.Test(firstName=234))
我们发现随着嵌套对象属性发生改变clone对象里面得嵌套对象属性也发生了改变 这其实就是”嵌套得对象“会在原来的对象和它的副本之间共享。
也就是说clone之后嵌套得对象是指向同一块内存得。
其实浅拷贝是复制对象的所有变量都含有与原来的对象相同的值,但是对其对象里面得对象并没有复制。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象 里面的对象
深拷贝:
深拷贝则是相反它不仅会拷贝主对象里面得所有变量也会对其嵌套对象进行拷贝并且重新分配内存从而各自独立。这其实也是一种递归行为相对于浅拷贝速度较慢增大了开销。
代码示例:
public class Girl implements Cloneable {
private Integer age;
private String sex;
private String name;
private Test test;
@Override
public Object clone() throws CloneNotSupportedException {
Girl girl = (Girl) super.clone();
//girl.setTest();
Test clone =(Test) girl.getTest().clone();
girl.setTest(clone);
return girl;
}
@Data
public static class Test implements Cloneable {
private String firstName;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}
public static void main(String[] args) throws Exception {
Girl girl = new Girl();
girl.setAge(18);
girl.setSex("女");
girl.setName("小艾");
Girl.Test test = new Girl.Test();
test.setFirstName("123");
girl.setTest(test);
// 拷贝girl 对象
Girl clone = (Girl) girl.clone();
// 修改test对象属性
test.setFirstName("234");
System.out.println("========clone" + clone);
System.out.println("=========girl" + girl);
}
输出结果:
cloneGirl(age=18,sex=女,name=小,test=Girl.Test(firstName=123))
girlGirl(age=18,sex=女,name=小,test=Girl.Test(firstName=234))
可以看出我们对其进行深拷贝之主对象里面得test对象属性发生改变clone之后对象并没有发生改变。从测面也说明了嵌套对象其实指向了不同内存。
明白了深拷贝与浅拷贝之后我们在返回来看下原型设计模式。
原型设计模式其实就是解决对象复制效率得问题。
这种模式其实不是太常用但是spring 提供BeanUtils.copyProperties本质上是浅拷贝,在使用过程中需要对嵌套对象或者集合进行额外处理。