23种设计模式之单例设计模式(二),Java程序员必读(从菜鸟到高手)架构师必备技能

书山有路勤为径,学海无涯苦作舟

今天这一篇,我们继续来讨论关于单例设计模式中的一些问题和细节

1.反射攻击,破坏单例模式

在单例设计模式中的所有实现中,都会存在反射攻击的安全隐患,接下来我们来看一段代码。研究一下为什么会存在反射攻击的隐患呢?

//老套路。来一段main方法
public class InnerClassSingletonTest{
    public static void main(String[] args) throws Exception{
        //接下来我们通过反射的方式来创建一个单例模式的实例
        //获取该类的构造方法
        Constructor<InnerClassSingleton> declaredConstructor=InnerClassSingleton.class.getDeclaredConstructor();
         declaredConstructor.setAccessible(true);
         //通过构造方法实例化
         InnerClassSingleton innerSingleton = declaredConstructor.newInstance();
         //通过正常调用实例化
         InnerClassSIngleton instance1= InnerClassSIngleton.getInstance();
         System.out.println(instance==insrance1);
         //控制台打印结果为false,单例被破坏,产生了两个对象
    }
}
//声明静态内部类创建方法的具体类
class InnerClassSingleton{
    private static InnerHolder{
       private static InnerClassSingleton instance=new InnerClassSingleton ();
    }
    private InnerClassSingleton(){}
    public InnerClassSingletongetInstance(){
     return InnerHolder.instance;
   }
}

破坏原因:class反射通过暴力反射的形式,强行获取到我们的构造方法,从而创建了实例,破坏单实例模式
那么我们来思考一下能不能防止反射攻击呢?答案是肯定的,可以防止
接下来我们再来看一段代码

//私有的构造方法
private InnerClassSingleton(){
   if(innerHolder.instance!=null){
    throw new RuntimeException("单例模式下不允许创建多实例");
  }
}

这样就可以防止反射攻击了
注意:只有饿汉模式和静态内部类的懒加载模式可以防止反射攻击,第一种懒加载是无法防止反射攻击的
备注:枚举不能被反射创建,同时也是线程安全的,基于JVM类加载机制(静态代码块)

2.序列化的能力,(数据的网络传递需要实现序列化)

只要让具体类实现一个接口即可(Serializable接口:起到一个标记的作用)
实现了序列化以后会破坏实力模式
解决方法
a.先动态生成序列化ID
b.在添加一个方法Object readResolve() throws ObjectStreamException{
return instance;
}

总结:以上就是单例设计模式的知识,希望能对你有所帮助,

欢迎各位码友交流!!!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值