使用反射对单例模式进行攻击的讨论

2023-11-13

我们都知道在单例模式中,对构造函数进行私有化private修饰,保证了类不能使用new进行对象的实例化,但是如果使用反射获取构造函数,在进行实例化就会导致private失效。

  1. 作者用中文作为类名,请读者勿怪,纯属喜好,工作中是不允许的哦~~
  2. java初级开发如有错误请多指正。
  3. 在构造函数中对实例是否存在进行判断,抛出异常,用于抵御反射攻击。

1.懒汉模式

public class 懒汉 {

    private static 懒汉 instance = null;

    //private保证无法new出对象
    private 懒汉(){
        if(instance!=null){
            throw  new RuntimeException("不允许多例");
        }
    }

    public static 懒汉 getInstance() throws InterruptedException {
        if(instance==null){
            Thread.sleep(100);
            instance=new 懒汉();
        }
        return instance;
    }

    public static void main(String[] args) throws InterruptedException {


        new Thread(()->{
            懒汉 a = null;
            try {
                a = 懒汉.getInstance();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(a);
        }).start();

        new Thread(()->{
            懒汉 a = null;
            try {
                a = 懒汉.getInstance();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(a);
        }).start();

    }
}

2.饿汉

public class Hungry {
    private static Hungry instance = new Hungry();

    private Hungry(){
        if(instance!=null){
            throw  new RuntimeException("不允许多例");
        }
    }

    public static Hungry getInstance(){
        return instance;
    }

    public static void main(String[] args) {
        //为什么这里可以new 因为这个main还在hungry类中声明
        Hungry instance = new Hungry();
        Hungry instance1 = Hungry.getInstance();
        Hungry instance2 = Hungry.getInstance();
        System.out.println(instance1==instance2);
    }

}

3.静态内部类
也是属于饿汉的一种,类加载时就创建实例

//利用类加载机制,饿汉的一种形式
public class 静态内部类 {

    private 静态内部类(){
        if(InnerClassHolder.instance!=null){
            throw  new RuntimeException("不允许多例");
        }
    }



    static class InnerClassHolder{
        private static 静态内部类 instance = new 静态内部类();
    }

    public static 静态内部类 getInstance(){
        return InnerClassHolder.instance;
    }

    public static void main(String[] args) {
        静态内部类 instance = 静态内部类.getInstance();
        静态内部类 instance2 = 静态内部类.getInstance();
        new Thread(()->{
            静态内部类 b = null;

                b = 静态内部类.getInstance();

            System.out.println(b);
        }).start();
        System.out.println(instance==instance2);
        System.out.println(instance);
    }
}

4.反射攻击


//反射对单例进行创建对象,是否会变成多例
//再次执行私有化构造函数创建对象
public class 反射攻击 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, InterruptedException {

        //通过在私有化构造函数中判断抛出异常抵御反射攻击

        //1-------------静态内部类------被反射攻击----异常抵御成功
//        //获取构造函数
//        Constructor<静态内部类> declaredConstructor = 静态内部类.class.getDeclaredConstructor();
//        //构造函数私有化在反射面前不值一提
//        //直接获取使用权
//        declaredConstructor.setAccessible(true);
//        //进行实例化
//        静态内部类 instance = declaredConstructor.newInstance();
//        静态内部类 instance1 = 静态内部类.getInstance();
//        System.out.println(instance1==instance);

        //2-------------懒汉------被反射攻击----异常抵御失败,因为懒汉是用到才创建对象,反射攻击时还不存在对象
//        //获取构造函数
//        Constructor<懒汉> declaredConstructor = 懒汉.class.getDeclaredConstructor();
//        //构造函数私有化在反射面前不值一提
//        //直接获取使用权
//        declaredConstructor.setAccessible(true);
//        //进行实例化
//        懒汉 instance = declaredConstructor.newInstance();
//        懒汉 instance1 = 懒汉.getInstance();
//        System.out.println(instance1==instance);

//        //3-------------饿汉------被反射攻击----异常抵御成功
//        //获取构造函数
//        Constructor<Hungry> declaredConstructor = Hungry.class.getDeclaredConstructor();
//        //构造函数私有化在反射面前不值一提
//        //直接获取使用权
//        declaredConstructor.setAccessible(true);
//        //进行实例化
//        Hungry instance = declaredConstructor.newInstance();
//        Hungry instance1 = Hungry.getInstance();
//        System.out.println(instance1==instance);
    }
}

这里说明一下,只有懒汉模式有被攻击的风险,由于懒汉模式的实例是在第一次使用时才被创建,所以如果最开始就使用反射创建对象会出现多例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用反射对单例模式进行攻击的讨论 的相关文章

  • 使用 proguard 混淆文件名

    我正在使用 proguard 和 Android Studio 混淆我的 apk 当我反编译我的apk时 我可以看到很多文件 例如aaa java aab java ETC 但我项目中的所有文件都有原始名称 有没有办法混淆我的项目的文件名
  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • Java LostFocus 和 InputVerifier,按反向制表符顺序移动

    我有一个 GUI 应用程序 它使用 InputVerifier 在产生焦点之前检查文本字段的内容 这都是很正常的 然而 昨天发现了一个问题 这似乎是一个错误 但我在任何地方都找不到任何提及它的地方 在我将其报告为错误之前 我想我应该问 我在
  • 我们可以有条件地声明 spring bean 吗?

    有没有一种方法可以有条件地声明 Spring bean 例如
  • 有人用过 ServiceLoader 和 Guice 一起使用吗?

    我一直想通过我们的应用程序 构建系统进行更大规模的尝试 但更高的优先级不断将其推到次要地位 这似乎是加载 Guice 模块的好方法 并且避免了关于 硬编码配置 的常见抱怨 单个配置属性很少会自行更改 但您几乎总是会有一组配置文件 通常用于不
  • java中如何知道一条sql语句是否执行了?

    我想知道这个删除语句是否真的删除了一些东西 下面的代码总是执行 else 是否删除了某些内容 执行此操作的正确方法是什么 public Deleter String pname String pword try PreparedStatem
  • JOOQ 忽略具有默认值的数据库列

    看来JOOQ完全忽略了数据库列的默认值 既不会更新 ActiveRecord 对象 也不会在 INSERT 时跳过此列 相反 它尝试将其设置为 NULL 这在 NOT NULL 列上失败 Example CREATE TABLE bug f
  • Java AES 256 加密

    我有下面的 java 代码来加密使用 64 个字符密钥的字符串 我的问题是这会是 AES 256 加密吗 String keyString C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE
  • 为什么解析这个 JSON 会抛出错误?

    我正在尝试解析这个 JSONObject query yahoo count 1 results rate Name USD INR id USDINR Time 12 19pm Date 10 31 2015 Bid 65 405 Ask
  • 如何自定义舍入形式

    我的问题可能看起来很简单 但仍然无法得到有效的东西 我需要自定义 Math round 舍入格式或其他格式以使其工作如下 如果数字是 1 6 他应该四舍五入到 1 如果大于或等于 1 7 他应该四舍五入到 2 0 对于所有其他带有 6 的小
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Android计算两个日期之间的天数

    我编写了以下代码来查找两个日期之间的天数 startDateValue new Date startDate endDateValue new Date endDate long diff endDateValue getTime star
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • 带 getClassLoader 和不带 getClassLoader 的 getResourceAsStream 有什么区别?

    我想知道以下两者之间的区别 MyClass class getClassLoader getResourceAsStream path to my properties and MyClass class getResourceAsStre
  • 使用 DBCP 配置 Tomcat

    在闲置一段时间 几个小时 后 我们收到了 CommunicationsException 来自 DBCP 错误消息 在异常中 位于这个问题的末尾 但我没有看到任何配置文件中定义的 wait timeout 我们应该看哪里 在 tomcat
  • 在会话即将到期之前调用方法

    我的网络应用程序有登录的用户 有一个超时 在会话过期之前 我想执行一个方法来清理一些锁 我已经实现了sessionListener但一旦我到达public void sessionDestroyed HttpSessionEvent eve

随机推荐

  • ZooKeeper(一):基础介绍

    文章目录 什么是 ZooKeeper ZooKeeper 发展历史 ZooKeeper 应用场景 ZooKeeper 服务的使用 ZooKeeper 数据模型 data tree 接口 znode 分类 总结 什么是 ZooKeeper Z
  • 机器学习-Sklearn-11(支持向量机SVM-SVC真实数据案例:预测明天是否会下雨)

    机器学习 Sklearn 11 支持向量机SVM SVC真实数据案例 预测明天是否会下雨 11 SVC真实数据案例 预测明天是否会下雨 这个案例的核心目的 是通过巧妙的预处理和特征工程来向大家展示 在现实数据集上我们往往如何做数据预处理 或
  • Java中ASCII码与字符之间的相互转换

    ASCII码转字符 char word char 97 强制转换 字符转ASCII码 int value a 加
  • STM32 进阶教程 17 - ADC注入通道

    前言 STM32 的ADC的一个强大功能是支持触发注入功能 在103中每个ADC模块支持4个注入通道 每个注入通道具有独立的结果突存器 注入通道具有较规划通道更高的优先级 在实际工程应用中 注入通道更多地会使用外部触发方式进行触发转换 关于
  • 时序预测相关技术分享

    时序预测相关技术分享 时序预测是指对时间序列数据进行预测 以预测未来的趋势或行为 在实际生产和应用中 时序预测广泛应用于金融 电力 交通等领域 时序预测可以帮助人们更好地理解和掌握未来的趋势和规律 从而做出更明智的决策 时序预测技术的方法和
  • 两个虚拟机互相拷贝文件或者文件夹

    互相拷贝文件 scp root k8s images tar bz2 root 192 168 33 16 root 将mysql配置文件上传到16服务器相应文件夹内 scp root 192 168 33 16 etc mysql my
  • React + Ts 实现三子棋小游戏

    在这里阅读效果更佳 还记得当年和同桌在草稿纸上下三子棋的时光吗 今天我们就用代码来重温一下年少 假设你有react基础 没有也行 只要你会三大框架的任意一种 上手react不难 游戏规则 双方各执一子 在九宫格内一方三子连成线则游戏结束 九
  • 为什么程序员都想进互联网大公司,看看福利就知道了

    每年年的最后一个月 一年的辛苦不易除了放假就盼着年终奖了 一直以来被外行人称为 钱多话少 的程序员 到了年底也都能拿到不少的年终奖 毕竟都是996拼出来的 那么国内的互联网年终奖能拿到多少呢 年终奖只是一个平均的 因为每个人的入职时间不同
  • linux离线安装glibc.i686

    一 下载相关rpm包 链接 https pan baidu com s 1Of1myRZa2ClrlSYw43OR3Q 提取码 hlsq 二 将相关rpm包复制到服务器上 三 执行sh install sh即可
  • 如果当前node.js版本和项目需要版本不一样,卸载重装其他版本node.js的方法

    其实这种node js版本不一样的问题 可以选择用nvm来管理node js的不同版本 此处仅总结卸载当前版本node js 重新安装所需版本node js的方法 另 现在 用Vite官网里面的 yarn npm等 的方法 创建Vue3项目
  • DOPI EV200轻松跑debain+jupyter

    硬件 DOPI EV200开发板 一张16G的TF卡 一条usb线 安装好RNIDS驱动 并分配IP地址 详细参考玩转rtsp一文章 上电启动后 程序从Nand Flash启动后 文件系统制作在TF卡中 debain jupyter在1 3
  • ST-Link/v2驱动安装

    链接 https pan baidu com s 1ZXAxwZa46z6K8 U3HW0qvg 提取码 ofmu 从连接里拿到一个名为en stsw link009 v2 0 2 zip的压缩包 如上图所示 新建一个文件夹 ST Link
  • 【微信小程序】文章设置

    设置基本字体样式 行高 首行缩进 font size 32rpx line height 1 6em text indent 2em padding 20rpx 0 border bottom 1px dashed var themColo
  • rabbitmq基础7——队列和消息过期时间设置、死信队列、延迟队列、优先级队列、回调队列、惰性队列

    文章目录 一 过期时间 1 1 针对队列设置 1 2 针对消息设置 二 死信队列 2 1 死信交换器 2 2 死信队列原理 2 3 延迟队列 特殊用法 三 优先级队列 3 1 监控页面创建优先级队列 3 2 监控页面创建优先级消息 四 回调
  • 【有限元分析】网格形状和网格尺寸对结果的影响——以矩形杆的静力分析为例

    本文研究了网格形状和网格尺寸对计算结果的影响 现研究一个矩形截面的杆件 如图1 1 对其末端施加两种等效的载荷 在末端面施加remote force 100N的力 如图1 2所示 对杆件进行2种网格形状划分 分别是六面体网格和四面体网格 如
  • 金融术语总结

    洗钱 将犯罪或其他非法违法行为所获得的违法收入 通过各种手段掩饰 隐瞒 转化 使其在形式上合法化的行为 存量客户 某个时间段里原先已有的客户 与新增客户相对应 月活跃用户数量 MAU Monthly Active User MAU 是当月登
  • 网页常用小技巧(JavaScript)

    1 nc ntextmenu window event returnValue false 将彻底屏蔽鼠标右键 table border border td no td table 可用于Table 2 取消选取 防止复制 3 npaste
  • java日志框架详解

    一 日志的概念 日志文件是用于记录系统操作事件的文件集合 可分为事件日志和消息日志 具有处理历史数据 诊断 问题的追踪以及理解系统的活动等重要作用 二 现有的日志框架 JUL java util logging logback log4j
  • Swagger注解详解

    目录 1 Api 2 APiOperation 3 ApiImplicitParams 4 ApiResponses 5 ApiModel 6 ApiModelProperty 这里是说明常用注解的含义和基本用法 也就是说已经对swagge
  • 使用反射对单例模式进行攻击的讨论

    我们都知道在单例模式中 对构造函数进行私有化private修饰 保证了类不能使用new进行对象的实例化 但是如果使用反射获取构造函数 在进行实例化就会导致private失效 作者用中文作为类名 请读者勿怪 纯属喜好 工作中是不允许的哦 ja