通过反射机制/反序列化破解单例模式

一、懒汉式单例

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

}

  运行结果截图如下:

  

猜你喜欢

转载自www.cnblogs.com/aeon/p/10212065.html