设计模式系列—单例设计模式( 三 )

先写一个利用反射获取实例的方法和直接获取实例的方法 , 将两者的返回值进行比较 , 看返回的是否是一个实例 。 代码如下:
package com.niuh.designpattern.singleton.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;/** * 反射攻击实例 */public class Reflectattack {public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {Constructor declaredConstructor = HungrySingleton.class.getDeclaredConstructor();declaredConstructor.setAccessible(true);HungrySingleton hungrySingleton = declaredConstructor.newInstance();HungrySingleton instance = HungrySingleton.getInstance();System.out.println(hungrySingleton);System.out.println(instance);System.out.println(hungrySingleton == instance);}}运行后的结果为:可见 , 两者的结果并不是一个对象 , 则饿汉模式依然受到了反射的攻击 。
设计模式系列—单例设计模式文章插图
那么该如何解决这反射攻击呢?我们知道是在类加载的时候就加载了这个实例的 , 因为是在类加载的时候就生成了词实例 , 那么我们可以在构造器里面加一个判断 , 进行反射防御 。 代码如下:
设计模式系列—单例设计模式文章插图
测试结果为:
设计模式系列—单例设计模式文章插图
这种方式有一个特点 , 也就是它对类加载这个时刻就把对象创建好的这种类是ok的 , 静态内部类的单例也可以用 。 对于不是静态类的也需要解决下 , 要根据创建实例的顺序进行解决 。 但是无论如何反射都可以访问到类的方法和变量 , 进行修改 , 所以非类加载这个时刻就把对象创建好的这种类 , 是不能防止反射攻击的 。
源码中的应用//JDK --tt-darkmode-color: #1A74FF;">
【设计模式系列—单例设计模式】文章持续更新 , 可以公众号搜一搜「 一角钱技术 」第一时间阅读 。 本文 GitHub org_hejianhui/JavaStudy 已经收录 , 欢迎 Star 。