当前位置: 首页 > article >正文

Java设计模式(单例模式)——单例模式存在的问题(完整详解,附有代码+案例)

文章目录

    • 4.3 单例模式存在的问题
      • 4.3.1序列化反序列化破环单例模式
      • 4.3.2 反射破环单例模式

4.3 单例模式存在的问题

破坏单例模式:

使上面定义的单例类(Singleton)可以创建多个对象,枚举方式除外。有两种方式,分别是序列化反序列化和反射来破坏单列模式。

4.3.1序列化反序列化破环单例模式

序列化反序列化破环单例模式

// 懒汉式-方式4(静态内部类方式)
//序列化反序列化破环单例模式
public class Singleton implements Serializable {

    // 私有构造方法不让外界创建本类的对象
   private Singleton(){};

    // 定义静态内部类 实现单例模式
    private static class SingletonHolder{
        // 在内部类中声明并初始化外部类的对象
        // 在内部类中声明并初始化外部类的对象
        //static:保证只创建一次,final:防止外界对其修改
        private static Singleton INSTANCE = new Singleton();

    }

    // 提供对外公共的访问方式
    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }

}
===========================================================
  public class Test {
    public static void main(String[] args) throws Exception{
//序列化反序列化破环单例模式

        //往文件中写对象
        // writeObjFile();

        //从文件中读取对象
        Singleton instance1 = readObjFile();
        Singleton instance2 = readObjFile();

        // singleton.demo8.Singleton@3b9a45b3
        System.out.println(instance1);
      
        // singleton.demo8.Singleton@7699a589
        System.out.println(instance2);

        boolean b = instance1 == instance2;
        System.out.println(b);//false
        //false说明创建的是两个Singleton类的对象,违背了单一规则
    }
    
    // 定义方法,将对象写出到文件中----序列化
    public static void writeObjFile() throws IOException {
        //获取Singleton类的对象
        Singleton instance = Singleton.getInstance();

        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(
          new FileOutputStream("pattern\\file\\1.txt"));
      
        //将instance对象写出到文件中
        oos.writeObject(instance);

    }

    // 定义方法,将文件中的序列化对象进行反序列化读入
    public static Singleton readObjFile() throws Exception{
        //创建输入流对象
        ObjectInputStream ois = new ObjectInputStream(
              new FileInputStream("pattern\\file\\1.txt"));
      
      	//第一个读取Singleton对象
        Singleton instance = (Singleton) ois.readObject();
        return instance;
    }

    // main end.....
}

4.3.2 反射破环单例模式

// 懒汉式-方式4(静态内部类方式)
//反射破环单例模式
public class Singleton {
    // 私有构造方法不让外界创建本类的对象
    private Singleton (){}

    // 定义静态内部类
    private static class SingletonHolder{
        // 在内部类中声明并初始化外部类的对象
        // 在内部类中声明并初始化外部类的对象
        //static:保证只创建一次,final:防止外界对其修改
  private static final Singleton INSTANCE = new Singleton();
    }

    // 提供对外公共的访问方式
    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}
============================================================
public class Test {
 public static void main(String[] args) throws Exception {

        //1. 获取Singleton类的字节码文件
        Class<Singleton> aClass = Singleton.class;

        //2. 获取空参构造方法
        Constructor cons = aClass.getDeclaredConstructor();

        // 3.因为空参构造是私有的,所以要取消访问检查才能创建对象
        cons.setAccessible(true);

        // 4.创建Singleton对象
        Singleton instance1 = cons.newInstance();
        Singleton instance2 = cons.newInstance();
        boolean b = instance1 == instance2;
        System.out.println(b);//false
        //false说明创建的是两个Singleton类的对象,违背了单一规则

    }
}

http://www.kler.cn/a/315425.html

相关文章:

  • JWT深度解析:Java Web中的安全传输与身份验证
  • 论文阅读《BEVFormer v2》
  • 以色列支付龙头遭DDoS攻击,各地超市加油站等POS机瘫痪
  • macOS解决U盘装完系统容量变小的问题
  • 24/11/13 算法笔记<强化学习> DQN算法
  • react动态路由
  • svn 1.14.5
  • numpy的花式引用
  • 3款免费的GPT类工具
  • Git 原理(提交对象)(结合图与案例)
  • 前后端分离项目中如何保证 API 安全
  • leetcode第十题:正则表达式匹配
  • (k8s)kubernetes 部署Promehteus学习之路
  • C语言:冒泡排序的注意事项及具体实现
  • Linux 基础IO 1
  • set的相关函数(3)
  • Node.js的学习2——内置模块(一)
  • 电气设备施工现场风险状态判断ai模型训练数据集
  • 【沪圈游戏公司作品井喷,游戏产业复兴近在眼前】
  • 整数二分算法和浮点数二分算法
  • 【数据结构与算法 | 灵神题单 | 二叉搜索树篇】力扣653
  • 基于SpringBoot的在线点餐系统【附源码】
  • 【C++笔记】C++编译器拷贝优化和内存管理
  • 【Obsidian】当笔记接入AI,Copilot插件推荐
  • SpringCloud alibaba
  • 算法-环形链表(141)