单例与序列化剖析:解决的三种方法
来源:互联网 发布:mac梦幻西游连接失败 编辑:程序博客网 时间:2024/06/06 07:14
false
com.webex.refactor.SingleModule@1a758cb
com.webex.refactor.SingleModule@10b30a7
可见单例在反序列化中不能保持单例。
正常情况下:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class SingleModule implements Serializable {
private static final long serialVersionUID = -6320624173133283454L;
public static SingleModule getInstance() {
return new SingleModule();
}
private SingleModule() {
}
}
public class SerializeTool {
private static byte[] objectStore;
private final static SingleModule originSingle;
private static SingleModule newSingle;
static {
originSingle = SingleModule.getInstance();
}
private static void verifyResult() {
// TODO Auto-generated method stub
System.out.println(newSingle == originSingle);
System.out.println(newSingle);
System.out.println(originSingle);
}
private static void deserializeUtil() {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
objectStore);
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(byteArrayInputStream);
Object readObject = objectInputStream.readObject();
newSingle = (SingleModule) readObject;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeStream(objectInputStream);
closeStream(byteArrayInputStream);
}
}
private static void serializeUtil(SingleModule singleModule) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(singleModule);
objectStore = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeStream(objectOutputStream);
closeStream(byteArrayOutputStream);
}
}
private static void closeStream(Closeable Stream) {
if (Stream != null) {
try {
Stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
serializeUtil(originSingle);
deserializeUtil();
verifyResult();
}
}
解决方法有3种:
(1)将单例作为成员存在,反序列化对象再读成员变量
(2)定制readResolve(), 带有对象引用类型的所有实例域都必须声明transient,主要出于安全考虑。如果应用在final类中用,应设置为private,如果是类为非final,且其子类没有覆盖readResolve()那么会产生一个超类实例,可能以后导致ClassCastException;
public class Singleton implements java.io.Serializable {
}
(3)定义成单元素枚举:
public enum Elvis{
INSTANCE
}
方法三是最好的方式。支持序列化,
- 单例与序列化剖析:解决的三种方法
- 序列化对象的三种方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- C# 的三种序列化方法
- 单例模式的三种方法
- Json数据的序列化与反序列化的三种常用方法介绍
- Json数据的序列化与反序列化的三种常用方法介绍
- 单例的序列化与反序列化
- 单例与序列化的那些事儿
- 单例与序列化的那些事儿
- 单例与序列化的那些事儿
- js判断两个日期只差
- 明确目标
- RadControls for ASP.NET AJAX
- Restaurant Nutrition:美食应用新思路
- 2011.8.22-26周总结
- 单例与序列化剖析:解决的三种方法
- BW R3 数据源分析(SBIW/LBWE)
- js判断输入的字符串是否是日期格式
- Activiti组件(翻译了一部分)
- iPhone/Mac Objective-C内存管理教程和原理剖析
- log4j.dtd URL
- Android Donut Makefile分析之一 (build/envsetup.sh)
- 在windows xp系统下配置eclipse集成hadoop开发
- Android代码优化