码迷,mamicode.com
首页 > 其他好文 > 详细

单例模式-反射攻击的解决方案及原理分析

时间:2020-04-10 21:15:18      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:exception   实例   on()   tin   ring   throws   ret   静态类   new   

首先我们还是拿饿汉模式作为栗子进行测试,饿汉模式的代码如下:

public class HungrySingleton implements Serializable {

    private static final HungrySingleton instance;

    static {
        instance = new HungrySingleton();
    }
    private HungrySingleton(){
    }

    public static HungrySingleton getInstance(){
        return instance;
    }

    private Object readResolve(){
        return instance;
    }

  1、先写一个利用反射获取实例的方法和直接获取实例的方法,将两者的返回值进行比较,看返回的是否是一个实例。

代码如下:

public class Testreflection {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class object = HungrySingleton.class;
        Constructor constructor = object.getDeclaredConstructor();
        constructor.setAccessible(true);

        HungrySingleton instance = HungrySingleton.getInstance();
        HungrySingleton newInstance = (HungrySingleton) constructor.newInstance();

        System.out.println(instance);
        System.out.println(newInstance);
        System.out.println(instance == newInstance);

     }
    }

  运行后的结果为:可见,两者的结果并不是一个对象,则饿汉模式毅然受到了反射的攻击。

技术图片

 

2、那么改如何解决这反射攻击呢?我们知道是在类加载的时候就加载了这个实例的,因为是在类加载的时候就生成了词实例,那么我们可以在构造器里面加一个判断,进行反射防御。代码如下:

技术图片

 

测试结果为:

技术图片

这种方式有一个特点,也就是它对类加载这个时刻就把对象创建好的这种类是ok的,静态内部类的单例也可以用。
对于不是静态类的也需要解决下,要根据创建实例的顺序进行解决。但是无论如何反射都可以访问到类的方法和变量,进行修改,所以非
类加载这个时刻就把对象创建好的这种类,是不能防止反射攻击的。

 

单例模式-反射攻击的解决方案及原理分析

标签:exception   实例   on()   tin   ring   throws   ret   静态类   new   

原文地址:https://www.cnblogs.com/shenwen/p/12676119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!