博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
序列化与反序列化的单例模式实现和readResolve()【转】
阅读量:6281 次
发布时间:2019-06-22

本文共 3471 字,大约阅读时间需要 11 分钟。

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;
}
本文转自秋楓博客园博客,原文链接:http://www.cnblogs.com/rwxwsblog/p/6661719.html,如需转载请自行联系原作者
你可能感兴趣的文章
企业中最佳虚拟机软件应用程序—Parallels Deskto
查看>>
Nginx配置文件详细说明
查看>>
怎么用Navicat Premium图标编辑器创建表
查看>>
Spring配置文件(2)配置方式
查看>>
MariaDB/Mysql 批量插入 批量更新
查看>>
ItelliJ IDEA开发工具使用—创建一个web项目
查看>>
solr-4.10.4部署到tomcat6
查看>>
切片键(Shard Keys)
查看>>
淘宝API-类目
查看>>
virtualbox 笔记
查看>>
Git 常用命令
查看>>
驰骋工作流引擎三种项目集成开发模式
查看>>
SUSE11修改主机名方法
查看>>
jdk6.0 + Tomcat6.0的简单jsp,Servlet,javabean的调试
查看>>
Android:apk签名
查看>>
2(2).选择排序_冒泡(双向循环链表)
查看>>
MySQL 索引 BST树、B树、B+树、B*树
查看>>
微信支付
查看>>
CodeBlocks中的OpenGL
查看>>
短址(short URL)
查看>>