1. 程式人生 > >通過反射機制/反序列化破解單例模式

通過反射機制/反序列化破解單例模式

一、懶漢式單例

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(); } } }

  執行結果截圖如下: