反射破解
我們先看一段代碼
/**
* @Description:
* @ClassName design_pattern
* @Author: 王瑞文
* @Date: 2021/1/16 21:08
*/
public class Test {
//如何去破解單例
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//通過反射區拿到無參構造,設定訪問權限為可訪問,就可以區暴力破解
Constructor<Singleton2> declaredConstructor = Singleton2.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);//設定構造權限為可以訪問
Singleton2 singleton2=declaredConstructor.newInstance();//Singleton2 with modifiers "private"
System.out.println(singleton2);
}
}
破解類
public class Singleton2 {
/**
* 懶漢式,需要使用得時候才會被初始化
*/
private static Singleton2 singleton = null;
//構造私有化
private Singleton2() {
}
//只能通過該方法獲得實體,但是在多執行緒的情況下可能會被初始化多次下
// public synchronized static Singleton1 getInstance() { 這么去加鎖的話 效率是很低的就變成了單執行緒但是可以去解決執行緒安全的問題
//雙重檢驗鎖,為了解決synchronized讀寫都加鎖
public static Singleton2 getInstance() {
//在第一次初始化物件的時候才去加鎖
if (singleton == null) {
synchronized (Singleton2.class) {
if (singleton == null) //只會有一個物件進入,再次判斷當前執行緒是不是應該去初始化物件
singleton = new Singleton2();
}
}
return singleton;
}
}
可以看出我們用單例是可以很簡單的去破解雙重檢驗鎖的單例模式的,我們通過反射去設定無參構造權限,這樣就把啊單例模式破解了
通過序列化去破解單例
/**
* @Description:
* @ClassName design_pattern
* @Author: 王瑞文
* @Date: 2021/1/16 21:19
*/
public class Test implements Serializable {
private static Test test = null;
public static void main(String[] args) {
//JAVA序列化技術
//物件從記憶體寫入到硬碟中(序列化)
//從硬碟讀取到記憶體(反序列化)
try {
//序列化
Test instance = Test.getInstance();
FileOutputStream fos = new FileOutputStream("D:\\test\\Test.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(instance);
oos.flush();
oos.close();
//反序列化
FileInputStream fis = new FileInputStream("D:\\test\\Test.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Test test1 = (Test) ois.readObject();
System.out.println(test1 == instance);
} catch (Exception e) {
e.printStackTrace();
System.out.println("出現例外");
}
}
private static Test getInstance() {
//在第一次初始化物件的時候才去加鎖
if (test == null) {
synchronized (Singleton2.class) {
if (test == null) //只會有一個物件進入,再次判斷當前執行緒是不是應該去初始化物件
test = new Test();
}
}
return test;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/250630.html
標籤:其他
上一篇:跨境電商獨立站優勢
