zoukankan      html  css  js  c++  java
  • 序列化与反序列化的单例模式实现和readResolve()

    如:
    public class SingleTest implements Serializable{
    private static final long serialVersionUID = -8600246627673134435L;
    private static class SingleTestHandler{
    private static SingleTest singleTest=new SingleTest();
    }
    private SingleTest() {
    }
    public static SingleTest getInstance(){
    return SingleTestHandler.singleTest;
    }
    /* protected Object readResolve(){
    System.out.println("调用了readResolve方法!");
    return SingleTestHandler.singleTest;
    }*/
    }
    class MyThead extends Thread{
    public void run(){
    System.out.println(SingleTest.getInstance().hashCode());
    }
    }
    class Test1{
    public static void main(String[] args) {
    try {
    SingleTest singleTest=SingleTest.getInstance();
    FileOutputStream fileOutputStream=new FileOutputStream(new File("myObjectFilee.txt"));
    ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
    objectOutputStream.writeObject(singleTest);
    objectOutputStream.close();
    fileOutputStream.close();
    System.out.println(singleTest.hashCode());
    } catch (IOException e) {
    e.printStackTrace();
    }
    try {
    FileInputStream fileInputStream=new FileInputStream(new File("myObjectFilee.txt"));
    ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
    SingleTest singleTest=(SingleTest) objectInputStream.readObject();
    objectInputStream.close();
    fileInputStream.close();
    System.out.println(singleTest.hashCode());
    } catch (IOException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }
    }
    加上注释运行结果证明返回的不是同一个实例:
    692404036
    931919113
    -----------------------------------------------------------------------------------------------------------------------------
    去掉注释运行结果为:
    692404036
    调用了readResolve方法!
    692404036
    证明为同一个实例
    -----------------------------------------------------------------------------------------------------------------------------
    那么这个readResolve()方法是从哪来的,为什么加上之后就能返回同一实例了呢?
    找到ObjectInputStream类的
    /**
    * Reads and returns "ordinary" (i.e., not a String, Class,
    * ObjectStreamClass, array, or enum constant) object, or null if object's
    * class is unresolvable (in which case a ClassNotFoundException will be
    * associated with object's handle). Sets passHandle to object's assigned
    * handle.
    */
    private Object readOrdinaryObject(boolean unshared)
    throws IOException
    {
    if (bin.readByte() != TC_OBJECT) {
    throw new InternalError();
    }

    ObjectStreamClass desc = readClassDesc(false);
    desc.checkDeserialize();

    Class<?> cl = desc.forClass();
    if (cl == String.class || cl == Class.class
    || cl == ObjectStreamClass.class) {
    throw new InvalidClassException("invalid class descriptor");
    }

    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;
    }
  • 相关阅读:
    雅虎天气接口
    解决activeandroid no such table
    解决Genymotion Error: “Unable to load VirtualBox Engine” on Yosemite. VirtualBox installed
    存金宝 价格提示
    添加 SSH 公钥
    ImportError: No module named flask.ext.wtf 解决方法
    Cannot fetch index base URL https://pypi.python.org/pypi/ 解决方法
    mac下只遍历目录不遍历文件
    dubbo源代码编译打包错误解决
    maven 基本配置
  • 原文地址:https://www.cnblogs.com/345214483-qq/p/6472158.html
Copyright © 2011-2022 走看看