序列化与反序列化的单例模式实现和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;
}









本文转自秋楓博客园博客,原文链接:http://www.cnblogs.com/rwxwsblog/p/6661719.html,如需转载请自行联系原作者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值