单例模式3-破坏单例(反射和序列化)

不法分子用反射破坏单例

我们知道反射可以破解private关键字,所以能够通过反射调用构造方法,具体如下:

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = LazyInnerClassSingleton.class;
        Constructor c = clazz.getDeclaredConstructor(null);
        c.setAccessible(true);
        LazyInnerClassSingleton lazy1 = c.newInstance();
        LazyInnerClassSingleton lazy2 = LazyInnerClassSingleton.getInstance();
        System.out.println(lazy1 == lazy2);//false
    }

那解决调用构造器来搞事情的反射也很简单,只要在构造方法加个判断就行:

private LazyInnerClassSingleton() {
    if (LazyHolder.LAZY!=null){
        throw new RuntimeException("不准搞事");
    }
}

重新执行上面的测试代码,可以发现反射搞不了事了。

序列化破坏单例

加个private Object readResolve(){}方法就可以了,具体的太长了自己看书吧。
虽然说,增加了readResolve()解决了反序列化单例模式被破坏的问题,但是会浪费性能,因为实际上被实例化了两次,那么有没有更好的做法呢?引出注册式单例模式

你可能感兴趣的:(单例模式3-破坏单例(反射和序列化))