package com.Enum;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
public class Singleton implements Serializable{
private static Singleton single=null;
private Singleton(){}
public static Singleton getSingle(){
synchronized(Singleton.class){
if(single==null)
single=new Singleton();
return single;
}
}
public static void reflectTest() throws Exception{
// 反射破坏单列模式
Class clas=Singleton.class;
Constructor cons=clas.getDeclaredConstructor();
//反射机制使得private方法可以被访问
cons.setAccessible(true);
//判断是否相等(结果false)
System.out.println(Singleton.getSingle()==cons.newInstance());
}
private Object readResolve(){
return single;
}
public static void serialzeTest() throws Exception{
//对象写入流中
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(Singleton.getSingle());
//更具字节流生成对象
ByteArrayInputStream bin=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bin);
Singleton singleton=(Singleton)ois.readObject();
//输出false
System.out.println(Singleton.getSingle()==singleton);
}
public static void main(String[] args) throws Exception{
Singleton.reflectTest();
Singleton.serialzeTest();
//输出true
System.out.println(Singleton.getSingle()==Singleton.getSingle());
}
}
防止序列化破坏单例,加入代码:
private Object readResolve(){
return single;
}
采用枚举实现最好,不仅线程安全还序列化保证,且不允许反射调用构造函数实例化。
private Object readResolve(){
return INSTANCE;
}