如何破坏单例模式?如何防止?

告别密码本!用Windows NPS给华为/华三交换机做Radius认证,SSH登录更安全 本文详细介绍了如何利用Windows NPS实现华为/华三交换机的Radius认证,提升SSH登录安全性。通过集中化管理、精细化控制和完整审计追踪,企业可告别传统密码本,大幅提升网络设备管理效率。文章包含NPS服务部署指南、交换机配置详解及调试技巧,助力企业构建安全高效的统一认证体系。 阅读详情

前几天看到一道面试题,问的是单例的模式书写以及单例模式能否被破坏?如何破坏?如何防止?

对于第一问单例模式的书写,了解过设计模式的同学对单例模式绝对不会陌生。常用的单例模式有懒汉式、饿汉式两种情况。实际的应用场景也是很常见,好比如数据库连接池的设计,还有Windows的Task Manager(任务管理器)。

单例模式的书写

这里列出懒汉式的写法

/**在多线程下如何保证单例模式需要记住三点。
  *第一就是双重加锁机制。
  *第二是确保SingleTest为volatile变量。
  *第三,是我觉得最容易被遗忘的一点,就是构造函数为private。
*/
public class SingleTest {

    public static volatile SingleTest singleTest ;

    private SingleTest(){
    }

    public static SingleTest getSingleTest(){
        if(singleTest==null){
            synchronized(SingleTest.class){
                if(singleTest==null){
                    singleTest = new SingleTest();
                }
            }
        }
        return singleTest;
    }
}

单例模式的破坏

上面的写法看起来没问题,但是存在安全问题。因为我们可以通过反射破坏单例模式。

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

        Constructor constructor = SingleTest.class.getDeclaredConstructor();
        constructor.setAccessible(true);

        SingleTest s1 = SingleTest.getSingleTest();
        SingleTest s2 = SingleTest.getSingleTest();
        SingleTest s3 = (SingleTest) constructor.newInstance();

        System.out.println("输出结果为:"+s1.hashCode()+"," +s2.hashCode()+","+s3.hashCode());
}
输出结果为:1286131032,1286131032,1581347769

从输出的结果我们就可以看出s1和s2为同一对象,s3为新对象。s3是我们通过反射机制,进而调用了私有的构造函数,然后产生了一个新的对象。

诶,既然单例模式存在漏洞,在JDK中那些应用单例模式的对象不是就会被恶意破坏了嘛。当时我也这样想的,我尝试了一下去破坏Runtime(在JDK为单例模式对象)。

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

    Constructor constructor1 = Runtime.class.getConstructor();
    Runtime r1 = (Runtime) constructor1.newInstance();
    Runtime r2 = Runtime.getRuntime();
    Runtime r3 = Runtime.getRuntime();

    System.out.println(r1.hashCode());
    System.out.println(r2.hashCode());
    System.out.println(r3.hashCode());
}

结果是被异常抛出,查看源码就看得出,JDK对已经封装好的单例对象是有保护机制的。

防止单例模式的破坏

那么我们如何去保护我们自定义的单例对象呢?很简单,只需要修私有的构造函数即可。

private static boolean flag = false;

private SingleTest(){
        synchronized(SingleTest.class){
            if(flag == false){
                flag = !flag;
            }else {
                throw new RuntimeException("单例模式被侵犯!");
            }
        }
 }
打通ZYNQ的任督二脉:AXI_FIFO数据交互全解析 FIFO(First In First Out,先进先出)是一种经典的数据缓冲结构,就像排队买票一样,先来的人先得到服务。时钟域交叉(CDC):连接不同时钟频率的模块数据缓冲:平衡生产者和消费者的速度差异流量控制:防止数据丢失或溢出input clk,// 输入AXI4-Stream接口(从PS到PL)// 输出AXI4-Stream接口(从PL到PS)// 状态指示信号// 定义状态机状态// 数据缓存// 8个深度的缓存// 流水线处理寄存器。 阅读详情

相关推荐

RealSense D455的标定并运行VINS-FUSION

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

qq_40186909的博客 2万+

请列举出至少4种单例可能被破坏的场景。

1反射对单例模式的破坏 采用反射的方式另辟蹊径实例了该类,导致程序中会存在不止一个实例。 解决方案 其思想就是采用一个全局变量,来标记是否已经实例化过了,如果已经实例化过了,第 二次实例化的时候,抛出异常 2clone()对单例模式的破坏 当需要实现单例的类允许clone()时,如果处理不当,也会导致程序中出现不止一个实例 解决方案 重写clone()方法,调clone()时直接返回已经实例的对象 3序列化对单例模式的破坏 在使用序列化/反序列化时,也会出现产生新实例对象的情况 解决方案 在反序列化

u010219345的博客 2064

蓝牙RSSI定位实战:用Arduino+BLE4.0搭建厘米级室内定位系统(附完整代码)

本文详细介绍了如何利用Arduino和BLE4.0模块构建厘米级精度的蓝牙RSSI室内定位系统。通过硬件选型、系统架构设计、三点定位算法实现及误差补偿技术,实现在商场导览、仓储管理等场景中的高精度定位。附完整代码和实测数据,帮助开发者快速部署商用级解决方案。

peace的博客 897

如何破坏单例模式?

所谓单例模式就是,某一个类只有一个实例,实现的核心就是将类的构造函数私有化, 只能由该类创建对象,其他对象就不能调用该类的构造函数,既不能创建对象。如何破坏单例?思考破坏单例之前,分析一个问题: 对象的创建方式有哪几种?四种: new、克隆、序列化、反射。标题可以改为:……其他对象就不能调用该类的构造函数,即不能通过new 来创建对象了。那么是否还有可以通过其他的三种方式创建对象呢,即其他三种方式

Android成长日记 555

企业微信审批流开发避坑指南:从零搭建自定义审批模板(含完整代码)

本文为企业微信审批流开发提供了从零搭建自定义审批模板的完整指南。通过对比内置模板与自建引擎的优劣,详细阐述了利用企业微信开放API和自建应用实现高度灵活审批流程的方案。文章重点解析了前端JS-SDK安全调用、后端签名生成与回调处理的核心代码,并分享了流程引擎设计、安全加固及性能监控等实战经验,帮助企业开发者避开常见陷阱,构建贴合业务的自定义审批系统。

weixin_28358083的博客 966

YOLOv11多模态融合实战:基于YOLOFuse的RGB与红外线(IR)协同检测技术解析

本文深入解析了YOLOv11多模态融合技术,重点介绍基于YOLOFuse框架的RGB与红外线(IR)协同检测方法。通过动态权重分配、跨模态特征对齐等创新设计,实现在低光照等复杂环境下的高精度目标检测,mAP提升高达37%。文章包含实战案例、训练技巧和部署方案,为计算机视觉开发者提供完整的多模态融合解决方案。

weixin_29038345的博客 290

四种单例模式-(破坏单例模式的三种方法)

【代码】四种单例模式-(破坏单例模式的三种方法)

qq_58706693的博客 371

Ubuntu桌面消失?可能是lightdm配置在捣鬼:详细解析/etc/lightdm.conf的优先级机制与实战修复

本文详细解析了Ubuntu系统因lightdm显示管理器配置错误导致桌面消失的问题。通过分析/etc/lightdm.conf的优先级加载机制,提供了从systemctl诊断、调试模式运行到实战修复配置语法错误(如缺失[Seat:*]组)的完整方案。文章还探讨了在系统无法启动时使用chroot或恢复模式进行高级救援,并对比了lightdm与gdm3在NVIDIA驱动环境下的不同表现,帮助用户高效恢复图形界面。

weixin_29313547的博客 420

单例模式(四种)与其破坏方式(三种)

单例模式 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。 单例模式的类型 单例模式有两种类型: 懒汉式:在真正需要使用对象时才去创建该单例类对象 饿汉式:在类加载时已经创建好该单例对象,等待被程序使用 饿汉式: 线程安全 不能实现延迟加载(浪费空间) public class Singleton { private stat

Pinker_Q 1291

【算法】基于STM32的MPU6050卡尔曼滤波算法(入门级)

1. 简介 卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。详情见:卡尔曼滤波简介 MPU6050的解算主要有三种姿态融合算法:四元数法 、一阶互补算法和卡尔曼滤波算法。我们常用的DMP库使用的是四元数法,本文采用卡尔曼滤波算法,使用RT-Thread国产操作系统,利用env工具进行串口、模拟IIC环境配置,使用10ms的线程进行卡尔曼滤波解算。 2.

weixin_44549777的博客 3万+

Meta开源Ego-Exo4D数据集:如何用1400小时多模态视频训练你的AI模型

Meta开源的Ego-Exo4D数据集包含1400小时多模态视频,涵盖第一人称和第三人称视角、眼动追踪、IMU传感器等多种模态,是AI模型训练的宝贵资源。本文详细介绍了从数据集下载、预处理到模型训练的全流程,帮助研究者高效利用这一多模态数据集进行AI模型开发。

weixin_29159441的博客 342

4种单例模式的写法,如何破解?如何防守?

从以上结果可以看出,4个单例模式中的前3个都被成功的创建出了两个对象,也就成功打破了单例模式的“单个对象”的保证,但第4个单例模式却失败了,异常错误提示:“无法反射式创建枚举对象”既然类加载器可以随意定义,那就将单例类将系统默认的那个类加载器做绑定,即在构造函数中判断类加载器是否与系统默认的类加载器相同,如果不同则抛出异常。《深入理解Java虚拟机》中说:对于任意一个类,都需要由加载的类加载器与这个类本身一同确定其在JVM中的唯一性,每个类加载器,都拥有一个独立的类名称空间。

booynal的博客 350

013:无人机航线规划的概念

航线规划是无人机任务规划的核心环节,它决定了无人机在整个任务执行过程中的飞行路径。航线规划需要考虑多种因素,包括飞行时间、飞行距离、能源消耗、飞行安全等。

qq_31762031的博客 2443

使用 `readResolve` 防止序列化破坏单例模式

在 Java 的单例模式中,序列化和反序列化可能会破坏单例的唯一性,而通过方法可以有效防止反序列化生成新对象,从而维护单例模式的约束。使用可以确保反序列化时返回的是现有的单例实例,而不是新的对象。对于需要持久化的单例类来说,这是一个非常重要的防御措施。确保你的单例模式在序列化和反射攻击下都具备防御机制,才能真正做到一个类的实例唯一。

weixin_54574094的博客 1557

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

单例模式的破坏及任何防止被破坏

常用的单例模式有懒汉式、饿汉式两种情况。实际的应用场景也是很常见,好比如数据库连接池的设计,还有Windows的Task Manager(任务管理器)等。 所谓单例模式就是,某一个类只能有一个实例,实现的核心就是将类的构造函数私有化,只能由该类创建对象,其他对象就不能调用该类的构造函数,即不能创建对象了。 现在看一个问题:对象的创建方式有哪几种? ...

menqiqi_的博客 568

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

java防止反射破坏单例模式

我们都知道单例模式是为了实现只创建一个实例,但是java 的反射机制可以破坏这种单例模式,这种通过反射来破坏单例的例子网上多的是,我就不列出来了,今天我们来说说怎么防止使用java的反射机制来破坏单例,查了查网上有很多是在单例的类中增加一个boolean类型的flag,然后在构造函数中来改变flag的值,然后再调用构造函数的时候判断这个flag是否已经改变了,这样来防止重复创建对象实例,当看到这种...

vasonyang随记 4122

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

防止单例模式被反射和单例模式破坏

反射破坏单例: 单例模式一般构造方法都是private,目的就是为了防止外界调用私有构造器创建多个实例,通过一个public的共有方法作为外界获取实例的唯一入口。从而实现单例。 但是反射能够访问私有的构造方法,只要反射获取的构造器调用setAccessible(true)方法即可。这样调用一次就会产生一个实例,调用多次就时多个实例,从而破坏单例。 如何防止: 只要在单例的私有构造器中添加判...

行走巨人国 2423

如何防止序列化破坏单例模式

反序列化时会调用readObject方法,里面会判断是否有重写readResolve方法,如果重写了就会执行readResolve方法,并将方法的返回值返回,我们可以利用这一点,在单例模式的类中实现readResolve方法,将单例对象返回回来,这样序列化就不能破坏单例了。反射和序列化都可以破解懒汉式和饿汉式。下面来讨论一下如何防止序列化来破坏单例模式,

远方的少年 498

③单例模式——如何防止反射破坏单例

一.在构造器中做判断,如果对象已经被创建那么再次创建则不允许创建 思路:不管是反射还是常规创建对象都需要调用构造器 弊端:如果在常规调用之前就已经使用反射创建则不能阻止 private volatile static SingleLazy instance; private SingleLazy(){ synchronized (this){ if(instance != null){ throw new Runtim

weixin_40565846的博客 2272

如何防止单例模式被破坏

以典型的双重锁效验机制为例 public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) {

蔡茂的博客 793

Java防止反射破坏单例模式

我们都知道单例模式是为了实现只创建一个实例,但是java 的反射机制可以破坏这种单例模式,这种通过反射来破坏单例的例子网上多的是,我就不列出来了,今天我们来说说怎么防止使用java的反射机制来破坏单例,查了查网上有很多是在单例的类中增加一个boolean类型的flag,然后在构造函数中来改变flag的值,然后再调用构造函数的时候判断这个flag是否已经改变了,这样...

阿里渣渣java研发组-群主 325

单例模式,以及防止单利被破坏的几种形式

单利模式:只允许创建一个实例 单利模式的几种实现方式: 饿汉式 /** * 饿汉式 * 优点:避免了多线程并发问题 * 缺点: 创建好的对象不是及时的调用会浪费内存空间 */ public class Hungry { private static Hungry hungry = new Hungry(); private Hungry(){} ...

Swh1234567的博客 501

别写错了,你知道如何防止 反射 和 序列化 破坏单例模式吗?

点击关注公众号,利用碎片时间学习反射破坏单例单例模式一般构造方法都是private,目的就是为了防止外界调用私有构造器创建多个实例,通过一个public的共有方法作为外界获取实例的唯一入口,从而实现单例。但是反射能够访问私有的构造方法,只要反射获取的构造器调用setAccessible(true)方法即可。这样调用一次就会产生一个实例,调用多次就时多个实例,从而破坏单例。...

Java笔记虾 555

java 防反射_java防止反射破坏单例模式

我们都知道单例模式是为了实现只创建一个实例,但是java 的反射机制可以破坏这种单例模式,这种通过反射来破坏单例的例子网上多的是,我就不列出来了,今天我们来说说怎么防止使用java的反射机制来破坏单例,查了查网上有很多是在单例的类中增加一个boolean类型的flag,然后在构造函数中来改变flag的值,然后再调用构造函数的时候判断这个flag是否已经改变了,这样来防止重复创建对象实例,当看到这种...

weixin_32516005的博客 398

如何防止反射破坏单例模式

Java设计模式之单例模式以及如何防止通过反射破坏单例模式-优快云博客

weixin_55453143的博客 425

Java设计模式系列--单例模式(枚举类防止破坏单例)

Java可以用枚举类写法来实现单例模式,它可以防止反射和序列化破坏单例。

IT利刃出鞘的博客 1061
上一篇: hadoop 之 MR程序报Type mismatch in value from map错
下一篇: 线程池参数解析
CallMeJiaGu
博客等级 码龄12年 149粉丝 99原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值