Prototype_原型模式
原型模式,就是拷贝,通过拷贝一个已经创建的原型实例,来创建一个和原型相同或相似的新对象。
Java中自带克隆方法,实现Cloneable接口,并重写clone方法。需要注意深拷贝和浅拷贝,默认方法是浅拷贝,即原型对象和克隆对象中的引用类型的对象所指向的地址值相同,都指向同一个对象,(就是克隆的时候是引用传递,不是值传递)。如果需要深拷贝可以通过改造clone方法,或通过序列化反序列化等方式来实现。
演示浅拷贝
- 实现Cloneable接口:这是一个标记性接口,里面没有需要我们实现的方法,不实现这个接口编译器不报错,但运行报错。
- 重写clone方法:Object对象中的clone方法是一个native方法,就是一个Java调用非Java代码的接口,clone方法是用C++写的,没有Java的原码,所有如果想使用clone方法必须重写clone方法。clone方法声明:
protected native Object clone() throws CloneNotSupportedException;
public class Person implements Cloneable{ public String name = "lin"; public Date date = new Date(); @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "name: "+name+"\ndate: "+date+"\ndateHash: "+date.hashCode(); } }
创建原型实例lin,并克隆出新实例copyLin。分别打印name,date,date的哈希值,实例的哈希值。
public static void main(String[] args) throws CloneNotSupportedException { Person lin = new Person(); Person copyLin = (Person) lin.clone(); System.out.println(lin.toString() + "\nhashcode: "+lin.hashCode()); System.out.println(copyLin.toString() + "\nhashcode: "+copyLin.hashCode()); }
测试结果,实例的哈希值不一样,说明真的新建了实例,但Date引用的哈希值一样,说明并没有克隆出新的Date,属于浅拷贝。
通过改造clone方法实现深拷贝
在重写clone方法时,将对象的引用也进行克隆
@Override protected Object clone() throws CloneNotSupportedException { Person person = (Person) super.clone(); person.date = (Date) this.date.clone(); return person; }
进行测试,克隆后修改了克隆实例引用的Date的值
public static void main(String[] args) throws CloneNotSupportedException { Person lin = new Person(); Person copyLin = (Person) lin.clone(); copyLin.date.setTime(100000000); System.out.println(lin.toString() + "\nhashcode: "+lin.hashCode()); System.out.println(copyLin.toString() + "\nhashcode: "+copyLin.hashCode()); }
结果只有克隆出来的实例的Date值被修改了,原型实例的Date值不变,说明是深克隆。
本文来自博客园,作者:独游空想家,转载请注明原文链接:https://www.cnblogs.com/linzhikai/p/16523052.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类