5.原型模式
- 原型模式:实现克隆
- javaScript继承是通过原型链来实现的。Prototype
- 以原来的对象为原型拷贝一份,进行修改,新对象和原对象一样
- 创建复杂对象时提高效率
5.1 深拷贝和浅拷贝
-
前提了解深拷贝和浅拷贝的区别:深拷贝和浅拷贝的区别
-
要点1:深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,是值引用,而对于对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址(地址引用),那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变。
-
java对象赋值是地址引用,两个对象地址相同
-
java的clone()方法是不彻底的深拷贝
-
- 完全深拷贝情况:对象内部都是基本数据类型属性
- 不彻底的深拷贝:对象内部存在引用数据对象
- 浅拷贝要转换深拷贝:实现Cloneable接口,覆盖并实现clone方法,除了调用父类中的clone方法得到新的对象, 还要将该类中的引用变量也clone出来
Object obj01 = (Person) obj.clone()
-
A类
public class Aclass implements Cloneable{
private Bclass bc;public Aclass() { } public Aclass(Bclass bc) { this.bc = bc; } public Bclass getBc() { return bc; } public void setBc(Bclass bc) { this.bc = bc; } @Override public Object clone() throws CloneNotSupportedException { Aclass ac = (Aclass)super.clone(); ac.bc = (Bclass)bc.clone(); return ac; }
}
- B类
public class Bclass implements Cloneable{
private Cclass cc;
public Bclass() {
}
public Bclass(Cclass cc) {
this.cc = cc;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Cclass getCc() {
return cc;
}
public void setCc(Cclass cc) {
this.cc = cc;
}
}
- C类
public class Cclass {
}
- 测试
public class TestClone {
@Test
public void testClone01() throws CloneNotSupportedException {
System.out.println("ac.hashCode() = "+ac.hashCode() +"|| ac1.hashCode() = "+ac1.hashCode());
System.out.println("ac == ac1 : " + (ac == ac1));
System.out.println(" ac.getBc().hashCode()=" + ac.getBc().hashCode() + "||ac1.getBc().hashCode()=" + ac1.getBc().hashCode());
System.out.println("ac.getBc() == ac1.getBc() : " + (ac.getBc() == ac1.getBc()));
System.out.println("ac.getBc().getCc().hashCode()=" + ac.getBc().getCc().hashCode() + "||ac1.getBc().getCc().hashCode()=" + ac1.getBc().getCc().hashCode());
System.out.println("ac.getBc().getCc() == ac1.getBc().getCc(): " + (ac.getBc().getCc() == ac1.getBc().getCc()));
}
}
- 结果呈现了:对象内部引用对象实现Cloneable接口,覆盖并实现clone方法,将外层对象由浅拷贝要转换深拷贝过程
ac.hashCode() = 231685785|| ac1.hashCode() = 114935352
ac == ac1 : false
ac.getBc().hashCode()=2110121908||ac1.getBc().hashCode()=32374789
ac.getBc() == ac1.getBc() : false
ac.getBc().getCc().hashCode()=1973538135||ac1.getBc().getCc().hashCode()=1973538135
ac.getBc().getCc() == ac1.getBc().getCc(): true
5.2 深克隆的方式
- 复制拷贝一种实现:IO流,效率低
- 另一种实现:内存拷贝,但java难以直接操作内存,需要使用C++的功能所以java调用的clone是本地方法
protected native Object clone() throws CloneNotSupportedException;
- 实现深克隆的方式
序列化反序列化,操作IO
将对象的属性也进行克隆
5.3 应用场景
- spring bean实现单例模式、原型模式
- 原型模式和工厂模式的协同使用
工厂模式中new->原型模式
- 原型对象十分复杂的情况创建另一个相同对象成本较大,所以用克隆方式来节省开销
本专栏下一篇:设计模式之适配器模式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123930.html