一、懒汉式单例
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(); } } }
运行结果截图如下: