单例模式()
通常情况下用以上方式实现的单例已经可以确保在系统中只存在唯一实例了但仍然有例外情况可能导致系统生成多个实例比如在代码中通过反射机制强行调用单例类的私有构造函数生成多个单例考虑到情况的特殊性本书中不对这种极端的方式进行讨论但仍有些合法的方法可能导致系统出现多个单例类的实例
一个可以被串行化的单例
public class SerSingleton implements javaioSerializable{
String name;
private SerSingleton() {
Systemoutprintln(Singleton is create)
//创建单例的过程可能会比较慢
name=SerSingleton;
}
private static SerSingleton instance = new SerSingleton()
public static SerSingleton getInstance() {
return instance;
}
public static void createString(){
Systemoutprintln(createString in Singleton)
}
private Object readResolve(){ //阻止生成新的实例总是返回当前对象
return instance;
}
}
测试代码如下
@Test
public void test() throws Exception {
SerSingleton s = null;
SerSingleton s = SerSingletongetInstance()
//先将实例串行化到文件
FileOutputStream fos = new FileOutputStream(SerSingletontxt)
ObjectOutputStream oos = new ObjectOutputStream(fos)
ooswriteObject(s)
oosflush()
oosclose()
//从文件读出原有的单例类
FileInputStream fis = new FileInputStream(SerSingletontxt)
ObjectInputStream ois = new ObjectInputStream(fis)
s = (SerSingleton) oisreadObject()
AssertassertEquals(s s)
}
使用一段测试代码测试单例的串行化和反串行化当去掉SerSingleton代码中加粗的readReslove()函数时以下测试代码抛出异常
junitframeworkAssertionFailedError: expected:javatuningchsingleton
serializationSerSingleton@ee
but was:javatuningchsingletonserializationSerSingleton@fec
说明测试代码中s和s指向了不同的实例在反序列化后生成多个对象实例而加上readReslove()函数的程序正常退出说明即便经过反序列化仍然保持了单例的特征事实上在实现了私有的readReslove()方法后readObject()已经形同虚设它直接使用readReslove()替换了原本的返回值从而在形式上构造了单例
注意序列化和反序列化可能会破坏单例一般来说对单例进行序列化和反序列化的场景并不多见但如果存在就要多加注意
返回目录Java程序性能优化让你的Java程序更快更稳定
编辑推荐
Java程序设计培训视频教程
JEE高级框架实战培训视频教程
JME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLEG数据库开发优化指南