欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > python >内容正文

python

python反序列化总结_单例模式的反序列化总结

发布时间:2024/7/23 python 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 python反序列化总结_单例模式的反序列化总结 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

最近观看effective in java ,提到单例模式创建过程中,如果是要保证该对象是可序列化的,需要考虑两点:

1、继承Serializable接口

2、增加readResolve方法

比较疑惑的是为什么需要增加这个方法,在以往的使用中需要被序列化的场景也不多,但是自己确实不明白这个单例对象在反序列化的时候会导致增加一个假冒的对象,从而’单例变的也不在单例‘

深入到代码细节观察发现:

ObjectInputStream反序列化会利用ObjectStreamClass序列化描述符创建一个实例

1、如果实例不为空

2、且描述符内检测到含有readResolve方法

3、反序列化中没有异常发生

满足以上条件会反射执行readResolve获取实例对象,并且和先前的对象作比较,不相等,用本次的值覆盖先前的返回值

不满足以上条件直接返回实例对象,完成反序列化

ObjectInputStream源码如下(标红部分):

private Object readOrdinaryObject(boolean unshared)

throws IOException

{

if (bin.readByte() != TC_OBJECT) {

throw new InternalError();

}

ObjectStreamClass desc = readClassDesc(false);

desc.checkDeserialize();

Object obj;

try {

obj = desc.isInstantiable() ? desc.newInstance() : null;

} catch (Exception ex) {

throw (IOException) new InvalidClassException(

desc.forClass().getName(),

"unable to create instance").initCause(ex);

}

passHandle = handles.assign(unshared ? unsharedMarker : obj);

ClassNotFoundException resolveEx = desc.getResolveException();

if (resolveEx != null) {

handles.markException(passHandle, resolveEx);

}

if (desc.isExternalizable()) {

readExternalData((Externalizable) obj, desc);

} else {

readSerialData(obj, desc);

}

handles.finish(passHandle);

if (obj != null &&

handles.lookupException(passHandle) == null &&

desc.hasReadResolveMethod())

{

Object rep = desc.invokeReadResolve(obj);

if (unshared && rep.getClass().isArray()) {

rep = cloneArray(rep);

}

if (rep != obj) {

handles.setObject(passHandle, obj = rep);

}

}

return obj;

}

-----------------------------------------------------------------------------------------------------------------------

测试程序如下:

package com.tt.st;

import java.io.ObjectStreamException;

import java.io.Serializable;

public class Singleton implements Serializable {

/**

*

*/

private static final long serialVersionUID = 2090309963475550553L;

private static final Singleton instance = new Singleton();

private Singleton() {

System.out.println(System.currentTimeMillis());

}

public static Singleton getInstance() {

return instance;

}

private Object readResolve()  throws ObjectStreamException {

return instance;

}

}

package com.tt.st;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

public class Main {

private static native ClassLoader latestUserDefinedLoader();

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

File file = new File("d:\\doc\\ab.out");

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));

Singleton singleton = Singleton.getInstance();

System.out.println("first: " + singleton);

objectOutputStream.writeObject(singleton);

objectOutputStream.close();

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));

Object object = objectInputStream.readObject();

System.out.println("second: " + object);

objectInputStream.close();

}

}

总结

以上是生活随笔为你收集整理的python反序列化总结_单例模式的反序列化总结的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。