破壞單例模式
單例模式,顧名思義,就是一個類在虛擬機中只能存在一個實例,那有沒有什麼方法可以破壞這個模式呢?看過下面的代碼你就明白了,方法還不少哦。
直接上代碼
/** 單例模式,隨便你哪種寫法*/
public class SingletonPattern implements Serializable, Cloneable{
private int age = 10;
private String name = "java";
private static class LazyHolder {
private static final SingletonPattern INSTANCE = new SingletonPattern();
}
private SingletonPattern (){}
public static final SingletonPattern getInstance() {
return LazyHolder.INSTANCE;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
protected SingletonPattern clone() throws CloneNotSupportedException {
SingletonPattern singletonPattern = (SingletonPattern)super.clone();
singletonPattern.age = this.age;
singletonPattern.name = new String(this.name);
return singletonPattern;
}
}
/** 破壞單例模式 */
public class BreakSingle {
/** 可以從heap dump中看出來有四個實例了 */
public static void main(String[] args) throws Exception{
SingletonPattern a = SingletonPattern.getInstance();
SingletonPattern a1 = SingletonPattern.getInstance();
System.out.println("a == a1 : " + (a == a1));
SingletonPattern b = getFromFile(a);
SingletonPattern c = reflect();
/* 克隆方式:已重寫克隆方法,注意深度克隆和淺克隆 */
SingletonPattern d = a.clone();
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
System.out.println("a == b : " + (a == b));
System.out.println("a == c : " + (a == c));
System.out.println("a == d : " + (a == d));
System.out.println("b == c : " + (b == c));
System.out.println("c == d : " + (c == d));
// Thread.sleep(1000000000);//此處休眠一下,可以使用jvisualvm查看實例個數
}
/** 序列化到文件 */
public static SingletonPattern getFromFile(SingletonPattern singletonPattern) throws Exception{
File file = new File("java.obj");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(singletonPattern);//寫到文件中
oos.close();
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
//從文件中讀出來
SingletonPattern singletonPatternFromFile = (SingletonPattern) ois.readObject();
ois.close();
return singletonPatternFromFile;
}
/** 反射方法 */
public static SingletonPattern reflect() throws Exception{
Constructor con = SingletonPattern.class.getDeclaredConstructor();
con.setAccessible(true);
return (SingletonPattern) con.newInstance();
}
}
運行結果
結果驗證
使用jvisualvm或者MAT等工具分析heap dump