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反序列化总结_单例模式的反序列化总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络数据链路层检错编码 --- 循
- 下一篇: ol xyz 加载天地图_OpenLay