通過反射機制/反序列化破解單例模式
阿新 • • 發佈:2019-01-03
一、懶漢式單例
package edu.aeon.model.singleton; /** * 單例模式:懶漢式(類裝載及建立) * 步驟: * 1.構造器私有化(防止外部new) * 2.提供靜態的、私有的代表該物件的例項的空引用 * 3.提供靜態的、公開的函式(方法)供外部訪問 * @author aeon */ public class LazySingleton { //1.構造器私有化(防止外部new) private LazySingleton(){} //2.提供靜態的、私有的代表該物件的例項的空引用(呼叫時才給值)private static LazySingleton lazySingletonInstance=null; //3.提供靜態的、公開的函式(方法)供外部訪問應用該模式唯一例項 public static LazySingleton getLazySingletonInstance(){ if(null==lazySingletonInstance){ lazySingletonInstance=new LazySingleton(); } return lazySingletonInstance; } }
二、破解單例模式(除列舉)
2.1通過反射機制來破解上面提供的懶漢式單例
package edu.aeon.model.singleton.crack; import java.lang.reflect.Constructor; import edu.aeon.model.singleton.LazySingleton; /** * [說明]:通過反射機制破解單例模式(除列舉) * 步驟: * 1.載入單例類 * 2.通過反射獲得無參構造器 * 3.解除本類訪問單例類私有屬性的限制(跳過許可權的檢查)。 * 4.通過反射獲得的無參構造器來獲得例項 * 5.對比獲得例項是否為同一物件 *@author aeon * */ public class CrackSingletonByReflex { public static void main(String[] args) { System.out.println("破解前:"+(LazySingleton.getLazySingletonInstance()==LazySingleton.getLazySingletonInstance()?"是同一物件!":"不是同一物件!")); try { //1.載入單例類 Class<LazySingleton> clazz = (Class<LazySingleton>) Class.forName("edu.aeon.model.singleton.LazySingleton"); //2.通過反射獲得無參構造器 Constructor<LazySingleton> constructor= clazz.getDeclaredConstructor(); //3.解除本類訪問單例類私有屬性的限制(跳過許可權的檢查)。 constructor.setAccessible(true); //4.通過反射獲得的無參構造器來獲得例項 LazySingleton lazySingleton1=(LazySingleton) constructor.newInstance(); LazySingleton lazySingleton2=(LazySingleton) constructor.newInstance(); //5.對比獲得例項是否為同一物件 System.out.println("破解後:"+(lazySingleton1==lazySingleton2?"是同一物件!":"不是同一物件!")); } catch (Exception e) { e.printStackTrace(); } } }
執行結果截圖如下: