单例模式5.1(序列化破坏单例)

 

之前见过可以通过反射来破坏单例,和如何防止被破坏。今天讲一下序列化破坏单例。

新建类 SerializableSingletion,其实就是饿汉式单例,只是实现了Serializable接口

public class SerializableSingletion implements Serializable {

    private final static SerializableSingletion SINGLETION = new SerializableSingletion();
    private SerializableSingletion(){

    }
    public static SerializableSingletion getInstance(){
        return SINGLETION ;
    }
}

新建测试类


public class Test {
    public static void main(String[] args) {
        SerializableSingletion s1 = SerializableSingletion.getInstance() ;
        SerializableSingletion s2 = null ;
        try{
            FileOutputStream fo  = new FileOutputStream("Serializable");
            ObjectOutputStream os = new ObjectOutputStream(fo);
            os.writeObject(s1);
            os.flush();
            os.close();

            FileInputStream fi = new FileInputStream("Serializable");
            ObjectInputStream os2 = new ObjectInputStream(fi);
            s2 = (SerializableSingletion) os2.readObject();
            os2.close();
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s1==s2);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

  通过验证,发现序列化已破坏单例。那如何去解决?在类中添加一个方法readResolve()

public class SerializableSingletion implements Serializable {

    private final static SerializableSingletion SINGLETION = new SerializableSingletion();
    private SerializableSingletion(){

    }
    public static SerializableSingletion getInstance(){
        return SINGLETION ;
    }

    private Object readResolve(){
        return  SINGLETION ;
    }
}

 跟踪源码如下图

 这个方法里面有判断是否存在readResolve方法

 源码里面

case TC_OBJECT:
    return checkResolve(readOrdinaryObject(unshared));  

继续跟踪readOrdinaryObject方法就会发现,如下图 就会判断是否包含readResolve方法,如果有就通过反射调用方法得到返回值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值