0958-72756125

我们只用绿色的食品原料

亚美体育网页版零食加工厂,只为您的健康着想

设计模式:深度洞察单例模式与序列化之间攻守道

本文摘要:导引本文将通过实例+阅读Java源码的方式先容序列化是如何破坏单例模式的,以及如何制止序列化对单例的破坏。单例模式,是设计模式中最简朴的一种。 通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界会见,从而利便对实例个数的控制并节约系统资源。如果希望在系统中某个类的工具只能存在一个,单例模式是最好的解决方案。关于单例模式的使用方式,可以阅读单例模式的七种写法可是,单例模式真的能够实现实例的唯一性吗?

亚美体育

导引本文将通过实例+阅读Java源码的方式先容序列化是如何破坏单例模式的,以及如何制止序列化对单例的破坏。单例模式,是设计模式中最简朴的一种。

通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界会见,从而利便对实例个数的控制并节约系统资源。如果希望在系统中某个类的工具只能存在一个,单例模式是最好的解决方案。关于单例模式的使用方式,可以阅读单例模式的七种写法可是,单例模式真的能够实现实例的唯一性吗?谜底是否认的,许多人都知道使用反射可以破坏单例模式,除了反射以外,使用序列化与反序列化也同样会破坏单例。序列化对单例的破坏首先来写一个单例的类:示例代码-01接下来是一个测试类:示例代码-02输出结构为false,说明:通过对Singleton的序列化与反序列化获得的工具是一个新的工具,这就破坏了Singleton的单例性。

这里,在先容如何解决这个问题之前,我们先来深入分析一下,为什么会这样?在反序列化的历程中到底发生了什么。ObjectInputStream工具的序列化历程通过ObjectOutputStream和ObjectInputputStream来实现的,那么带着刚刚的问题,分析一下ObjectInputputStream 的readObject 方法执行情况到底是怎样的。

亚美体育

为了节约篇幅,这里给出ObjectInputStream的readObject的挪用栈:这里看一下重点代码,readOrdinaryObject方法的代码片段:示例代码-03上面主要贴出两部门代码。先分析第一部门:示例代码-03.1这里建立的这个obj工具,就是本方法要返回的工具,也可以暂时明白为是ObjectInputStream的readObject返回的工具。其生成方式如下:isInstantiable:如果一个serializable/externalizable的类可以在运行时被实例化,那么该方法就返回true。

针对serializable和externalizable我会在其他文章中先容。desc.newInstance:该方法通过反射的方式挪用无参结构方法新建一个工具。

亚美体育网页版

所以。到现在为止,也就可以解释,为什么序列化可以破坏单例了?答:序列化会通过反射挪用无参数的结构方法建立一个新的工具。

那么,接下来我们再看刚开始留下的问题,如何防止序列化/反序列化破坏单例模式。防止序列化破坏单例模式先给出解决方案,然后再详细分析原理:只要在Singleton类中界说readResolve就可以解决该问题。

单例的类代码如下:示例代码-04继续运行以下测试类:本次输出效果为true,现在我们的单例就没有被破坏。详细原理,我们回过头继续分析示例代码-03中的第二段代码:示例代码-03.2hasReadResolveMethod:如果实现了serializable 或者 externalizable接口的类中包罗readResolve则返回trueinvokeReadResolve:通过反射的方式挪用要被反序列化的类的readResolve方法。所以,原理也就清楚了,主要在Singleton中界说readResolve方法,并在该方法中指定要返回的工具的生成计谋,就可以防止单例被破坏。


本文关键词:设计模式,深度,洞察,单例,模式,与,亚美体育网页版,序列化

本文来源:亚美体育网页版-www.jg580.com