反射技术破解单例模式

反射破解

我们先看一段代码

/**
 * @Description:
 * @ClassName design_pattern
 * @Author: 王瑞文
 * @Date: 2021/1/16 21:08
 */
public class Test {
    //如何去破解单例
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //通过反射区拿到无参构造,设置访问权限为可访问,就可以区暴力破解
        Constructor<Singleton2> declaredConstructor = Singleton2.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);//设置构造权限为可以访问
        Singleton2 singleton2=declaredConstructor.newInstance();//Singleton2 with modifiers "private"
        System.out.println(singleton2);
    }
}

破解类

public class Singleton2 {
    /**
     * 懒汉式,需要使用得时候才会被初始化
     */
    private static Singleton2 singleton = null;

    //构造私有化
    private Singleton2() {

    }

    //只能通过该方法获得实例,但是在多线程的情况下可能会被初始化多次下
    // public synchronized static Singleton1 getInstance() { 这么去加锁的话 效率是很低的就变成了单线程但是可以去解决线程安全的问题
    //双重检验锁,为了解决synchronized读写都加锁
    public static Singleton2 getInstance() {
        //在第一次初始化对象的时候才去加锁
        if (singleton == null) {
            synchronized (Singleton2.class) {
                if (singleton == null) //只会有一个对象进入,再次判断当前线程是不是应该去初始化对象
                    singleton = new Singleton2();
            }
        }
        return singleton;
    }
}

可以看出我们用单例是可以很简单的去破解双重检验锁的单例模式的,我们通过反射去设置无参构造权限,这样就把啊单例模式破解了

通过序列化去破解单例


/**
 * @Description:
 * @ClassName design_pattern
 * @Author: 王瑞文
 * @Date: 2021/1/16 21:19
 */
public class Test implements Serializable {
    private static Test test = null;

    public static void main(String[] args) {
        //JAVA序列化技术
        //对象从内存写入到硬盘中(序列化)
        //从硬盘读取到内存(反序列化)
        try {
            //序列化
            Test instance = Test.getInstance();
            FileOutputStream fos = new FileOutputStream("D:\\test\\Test.obj");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(instance);
            oos.flush();
            oos.close();
            //反序列化
            FileInputStream fis = new FileInputStream("D:\\test\\Test.obj");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Test test1 = (Test) ois.readObject();
            System.out.println(test1 == instance);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("出现异常");
        }

    }

    private static Test getInstance() {
        //在第一次初始化对象的时候才去加锁
        if (test == null) {
            synchronized (Singleton2.class) {
                if (test == null) //只会有一个对象进入,再次判断当前线程是不是应该去初始化对象
                    test = new Test();
            }
        }
        return test;
    }
}

插播一条招聘信息:

杭州百玩科技有限公司招募 !!!合伙人!!!啦~~~
我们是一家互联网公司,我们将要踏上中国玩具的征程,打响中国品牌,承载中国制造,传承中国文化,我们的征程是星辰大海!
盆友,世界那么大,该为你的梦想去闯一闯了,你的五行缺伯乐!
相信我,我们的梦想让你仰望星空!
相信我,我们的团队让你脚踏实地,足以安放你这么牛逼的灵魂!
相信我,我们的文化会令你振奋!
世界那么大,你不来,谁知道你牛逼?!
一群有情有义的人,期待你的加入!
简历投递:bavan_resume@163.com

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值