不法分子用反射破坏单例
我们知道反射可以破解private关键字,所以能够通过反射调用构造方法,具体如下:
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<LazyInnerClassSingleton> clazz = LazyInnerClassSingleton.class;
Constructor<LazyInnerClassSingleton> 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()解决了反序列化单例模式被破坏的问题,但是会浪费性能,因为实际上被实例化了两次,那么有没有更好的做法呢?引出注册式单例模式;