1.破坏
- 序列化
- 克隆
- 反射
2.破坏实战
package com.jun.design.pattern;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Singleton implements Serializable,Cloneable {
private static final long serialVersionUID = -3465901519138664777L;
private Singleton() {}
private static volatile Singleton instance;
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws IOException, ClassNotFoundException, CloneNotSupportedException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
System.out.println("序列化:");
Singleton originSingleton = Singleton.getInstance();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(Singleton.getInstance());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
Singleton serializeSingleton = (Singleton) objectInputStream.readObject();
System.out.println(originSingleton == serializeSingleton);
System.out.println("克隆:");
Singleton cloneSingleton = (Singleton) originSingleton.clone();
System.out.println(cloneSingleton == originSingleton);
System.out.println("反射:");
Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
Singleton reflectSingleton = declaredConstructor.newInstance();
System.out.println(originSingleton == reflectSingleton);
}
}
3.解决方案
- 防止序列化破坏 ,添加readResolve(),返回Object对象
- 防止克隆破坏,重写clone(),直接返回单例对象
- 防止反射,定义一个全局变量,当第二次创建的时候抛出异常
package com.jun.design.pattern;
import java.io.*;
import java.lang.reflect.Constructor;
public class SingletonResolve implements Serializable,Cloneable {
private static final long serialVersionUID = -2144773240242119659L;
private static volatile boolean isCreate = false;
private SingletonResolve(){
if(isCreate){
throw new RuntimeException("已经被实例化一次,不能在实例化");
}
isCreate = true;
}
private static volatile SingletonResolve instance;
public static SingletonResolve getInstance() {
if (instance == null) {
synchronized (SingletonResolve.class) {
if (instance == null) {
instance = new SingletonResolve();
}
}
}
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return instance;
}
private Object readResolve() {
return instance;
}
public static void main(String[] args) throws Exception{
System.out.println("序列化:");
SingletonResolve originSingletonResolve = SingletonResolve.getInstance();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(SingletonResolve.getInstance());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
SingletonResolve serializeSingletonResolve = (SingletonResolve) objectInputStream.readObject();
System.out.println(originSingletonResolve == serializeSingletonResolve);
System.out.println("克隆:");
SingletonResolve cloneSingletonResolve = (SingletonResolve) originSingletonResolve.clone();
System.out.println(originSingletonResolve == cloneSingletonResolve);
System.out.println("反射:");
Constructor<SingletonResolve> declaredConstructor = SingletonResolve.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
SingletonResolve reflectDeclaredConstructor = declaredConstructor.newInstance();
System.out.println(originSingletonResolve == reflectDeclaredConstructor);
}
}