常规的单例模式有以下几处缺点:
1.无法防止被反射,有人可能说加入flag变量控制,那么我在反射的时候提前修改flag,不就可以了么?
2.无法防止被序列化创建.
那么我们可以采用枚举的方式来优化.
public class SingleInstance {
public static void main(String[] args) throws Exception {
Single instance = Single.Instance;
System.out.println(instance.getAge() + "");
//枚举抗序列化
Single deepClone = deepClone(instance);
int age = deepClone.getAge();
System.out.println(instance==deepClone);
//枚举抗反射
Class<Single> clazz = Single.class;
Constructor<Single> constructor = clazz.getConstructor(null);
constructor.setAccessible(true);
Single single = constructor.newInstance(null);
}
public static <T> T deepClone(T src) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
T dest = (T) in.readObject();
return dest;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
enum Single {
Instance(10);
private int age;
private Single(int num) {
age = num;
}
public int getAge() {
return age;
}
}