原型模式的深浅复制和序列化
来源:互联网 发布:淘宝退款会影响信誉吗? 编辑:程序博客网 时间:2024/06/08 05:53
这是java的Object直接有方法的设计模式,面向对象的23种设计模式点这里。我们要做的只是实现Cloneable接口,这个接口的目的只是告诉jvm这个类的对象可以clone。同样的还有Serializable接口,今天说的跟它也有关系。
下面回到题目,复制和clone相信大家都知道。就是弄个一模一样的,而那个模子就叫原型。那么什么是深复制和浅复制呢?这和对象实现有关系,对象里的属性有基本类型和引用类型。一种复制是把基本类型复制,引用类型直接拿过来用。可以看出就复制一层就行了,所以叫浅复制。而深复制是把所有引用往下继续复制,直到全部属性是基本类型(对象属性最终存在计算机里是基本类型)。
那么Object的clone方法得到的是深复制还是浅复制呢。很遗憾是浅复制,为啥不是是深复制呢。因为浅复制简单,深复制还要考虑循环引用。先来看下浅复制
public class Prototype { static class Student implements Cloneable{//这里为了简单,直接public,实际中不推荐 public int id = 12345; public String name = "小明"; public Address address = new Address(); @Override public Student clone() throws CloneNotSupportedException { Student clone = (Student) super.clone();// clone.address = address.clone(); return clone; } } static class Address implements Cloneable{ public String name = "西湖";// @Override// public Address clone() throws CloneNotSupportedException {// return (Address) super.clone();// } } public static void main(String[] args) throws Exception { Student student = new Student(); Student clone = student.clone(); clone.id = 54321; clone.name = "小花"; clone.address.name = "瘦西湖"; System.out.println(student.id); System.out.println(student.name); System.out.println(student.address.name); }}输出结果为:12345小明瘦西湖
可以看出clone.address == student.address,是引用复制。细心的可能发现了student.name != clone.name,这是因为这里String类似与基本类型,具体可以看一下第一个的String例子。
那么怎么深度复制呢,只要使用上面注释掉的代码就可以了。输出结果为:
12345小明西湖
可以看出每个对象都得重写clone方法,所以引出了开头说的Serializable接口。这个是序列化接口,也叫串行化。串行我们知道就是把所有东西一条线上排好,听着就像流。其实序列化的目的就是为了传送对象,就是根据一个对象,在另一个地方生成一样的对象,这不就是我们要的复制吗。程序如下:
public class Prototype { static class Student implements Serializable {//这里为了简单,直接public,实际中不推荐 private static final long serialVersionUID = 6977402643848374753L; //因为实际应用中类是会改动的,UID用来判断类版本,默认为1L; public int id = 12345; public String name = "小明"; public Address address = new Address(); } static class Address implements Serializable { public String name = "西湖";// public Student student; } public static <T extends Serializable> T clone(T obj) throws Exception { T cloneObj; //写入字节流 ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); obs.writeObject(obj); obs.close(); //分配内存,写入原始对象,生成新对象 ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(ios); //返回生成的新对象 cloneObj = (T) ois.readObject(); ois.close(); return cloneObj; } public static void main(String[] args) throws Exception { Student student = new Student(); Student clone = clone(student);// student.address.student = student; clone.address.name = "瘦西湖"; System.out.println(student.address.name); }}
输出结果为: 西湖。可以看出直接是深复制,那么是不是循环引用也不用管了。我们同样把注释的可用,程序没有死循环,完美运行。当然序列化有个缺点就是效率低。
- 原型模式的深浅复制和序列化
- 原型模式深浅复制
- 原型模式中的深浅复制
- 原型模式之深浅复制
- 设计模式学习笔记九:原型模式(和深浅复制)
- 原型模式浅复制和深复制
- 深浅复制的区别
- 七、原型模式(深浅克隆)
- 原型模式(重新思考深浅拷贝)
- 深度揭秘原型(深浅克隆)模式!
- 关于Java和OC深浅复制的问题
- 深浅复制产生的根本原因
- NSString深浅复制的见解
- c#的各种深浅复制
- 引用类型的深浅复制
- 原型模式(简历的复制)
- 原型模式——浅复制和深复制
- 如何理解原型模式中的深复制和浅复制
- NLP中的新词发现特征选择
- 解决VM克隆CentOS系统后eth0消失,显示eth1的问题
- Tomcat 部署项目后,访问出现404
- 小程序微信支付申请
- 除了IPv4,还有IPv5、IPv6、IPv7和IPv9,IPv10
- 原型模式的深浅复制和序列化
- CSI.Bridge.2017.Advanced.v19.0.0.1294.Win32_64 2CD
- 自定义控件之绘图篇:Path之贝赛尔曲线和手势轨迹、水波纹效果
- Can't create handler inside thread that has not called Looper.prepare()解决方法
- jsp和js文件中获取EL表达式的值
- ECSHOP如何解决Deprecated: preg_replace()报错
- GRU神经网络
- 图解HTTPS
- 简单绘制饼状图