千家信息网

Java单例模式的攻击与防御怎么理解

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍"Java单例模式的攻击与防御怎么理解",在日常操作中,相信很多人在Java单例模式的攻击与防御怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"J
千家信息网最后更新 2026年11月01日Java单例模式的攻击与防御怎么理解

这篇文章主要介绍"Java单例模式的攻击与防御怎么理解",在日常操作中,相信很多人在Java单例模式的攻击与防御怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java单例模式的攻击与防御怎么理解"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

说到"单例模式被攻击"这个话题,大家最容易想到的可能就是通过序列化/反序列化来攻击单例模式,因为一个对象实例序列化再反序列化后,得到的新的对象虽然各字段内容和原字段一致,然而对象地址和原始对象地址相比已经发生了变化,因此它们是两个不同的对象。

上面的结论完全正确,然而除了序列化/反序列化,单例模式还可能遭受另一种方式的攻击,即反射攻击(Reflection attack)。

看一个具体例子:

public class JerrySingleton {   private String name;   private JerrySingleton(){   name = "Jerry";}private static class SingletonHolder{      private static final JerrySingleton INSTANCE = new JerrySingleton();}public static JerrySingleton getInstance() {      return SingletonHolder.INSTANCE;      }}

上面是一个饿汉式单例。

然而我只需要将这个单例类JerrySingleton的构造函数通过反射设置成可以访问Accessible,然后就能通过反射调用该构造函数,进而生成新的对象实例。这样就破坏了单例模式。

Class classType = JerrySingleton.class;Constructor c = classType.getDeclaredConstructor(null);c.setAccessible(true);JerrySingleton e1 = (JerrySingleton)c.newInstance();JerrySingleton e2 = JerrySingleton.getInstance();System.out.println(e1 == e2);

第6行代码会打印false。

针对这种攻击,一种可行的防御措施是在单例类的构造函数内定义一个布尔变量,初始化为false。当构造函数执行后,该变量被置为true。如果接下来构造函数再次被执行,则人为抛出异常,避免构造函数重复执行。

public class JerrySingletonImproved {    private static boolean flag = false;    private JerrySingletonImproved(){         synchronized(JerrySingletonImproved.class) {            if(flag == false) {                  flag = !flag;            }      else {              throw new RuntimeException("Singleton violated");      }  }}}

这种防御措施无法从根本上杜绝Singleton被攻击,因为攻击者仍旧可以通过反射来修改布尔变量flag的值,从而绕过这个检查。

最理想的不会受到攻击的单例模式实现是借助Java里枚举类Enumeration的特性:

这种实现类型的单例模式的消费代码:

System.out.println("Name:" + JerrySingletonAnotherApproach.INSTANCE.getName());

如果攻击者通过前面介绍的反射代码对这种实现方式的单例进行攻击,JDK会抛出NoSuchMethodException异常:

Exception in thread "main" java.lang.NoSuchMethodException: singleton.JerrySingletonAnotherApproach.()at java.lang.Class.getConstructor0(Class.java:3082)at java.lang.Class.getDeclaredConstructor(Class.java:2178)at singleton.SingletonAttack.test3(SingletonAttack.java:31)at singleton.SingletonAttack.main(SingletonAttack.java:43)

究其原因,是因为现在我们是通过Java枚举方式实现的单例,枚举类没有传统意义上的构造函数,因此对这种反射攻击免疫。

到此,关于"Java单例模式的攻击与防御怎么理解"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

攻击 模式 函数 防御 对象 序列 反射 学习 代码 变量 方式 接下来 地址 字段 实例 布尔 措施 攻击者 更多 帮助 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州紫鲸互联网科技有限公司 互联网和科技技术 腾讯阿里互联网科技 关于新基建和互联网科技 华宇互联网科技 致骋互联网科技 互联网 视角下的科技创新 成都狮子座互联网科技 互联网和高科技公司 互联网校园科技培训 呼和浩特新华互联网科技学院 青海科技产业互联网发展 无锡工业互联网科技有限公司 国大互联网教育科技有限公司薪资 黑科技 体验场景 互联网大会 富国互联网金融科技混合基金 互联网科技年终奖 扫呗互联网科技有限公司 互联网硬科技公司 艺电能源互联网科技有限公司招聘 互联网科技公司税收优惠 互联网公司 科技公司 兼蜜互联网科技 北京华百购互联网科技有限公司 昭通云南众福互联网科技有限公司 互联网经济与金融科技 互联网科技扶贫时间 迪庆互联网科技招生 广州新华互联网科技学校电竞方面 北京军民互联网科技公司
0