单例模式在序列化场景下实现

博客介绍了单例模式在序列化场景下的实现。单例有懒汉、饿汉等多种形式,单例要求构造私有、序列化反序列化唯一、线程实例唯一。一般单例类在序列化反序列化时会因反射调用构造方法破坏单例,需提供readResolve方法,而枚举单例无需该方法且不怕反射攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式在序列化场景下实现

单例有懒汉,饿汉,双重锁,静态内部类,枚举类

单例的要求:构造私有,序列化反序列化唯一,线程实例唯一

一般的单例类尽管构造方法私有,但在序列化再反序列化时,会通过反射调用对象的构造方法,造成单例对象的不唯一

故而在序列化反序列化时,单例类必须提供一个方法readResolve 返回值为单例实例

code:

单例类:
public class Singleton implements Serializable {
    private Singleton() {}

    public static Singleton getInstance() {
        return SingletonBuilder.INSTANCE;
    }
    /**
     * 用于反序列化时保持单例唯一
     */
    private Object readResolve() {
        return SingletonBuilder.INSTANCE;
    }
    /**
     * 静态内部类 延迟加载单例
     */
    static class SingletonBuilder {
        private static final Singleton INSTANCE = new Singleton();
    }
}

psvm主方法:
ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
ObjectOutputStream objectOs = new ObjectOutputStream(byteArrayOs);
// 对象写入流中
objectOs.writeObject(Singleton.getInstance());

ObjectInputStream objectIs = new ObjectInputStream(new ByteArrayInputStream(byteArrayOs.toByteArray()));
// 从流中读取的对象对比静态内部类单例获取的对象
System.out.println(objectIs.readObject() == Singleton.getInstance());

执行结果:

true

Process finished with exit code 0

枚举单例无需readResolve 且不怕反射攻击

public enum  EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值