唐山长城网站建设,合肥网站设计,四川住房建设和城乡建设厅网站,宝塔装wordpress最近观看effective in java #xff0c;提到单例模式创建过程中#xff0c;如果是要保证该对象是可序列化的#xff0c;需要考虑两点#xff1a;1、继承Serializable接口2、增加readResolve方法比较疑惑的是为什么需要增加这个方法#xff0c;在以往的使用中需要被序列化的…最近观看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 stubFile 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();}}