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

文章目录

4.3 单例模式存在的问题

破坏单例模式:

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

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

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

java 复制代码
// 懒汉式-方式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 反射破环单例模式

java 复制代码
// 懒汉式-方式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类的对象,违背了单一规则

    }
}
相关推荐
bkspiderx12 分钟前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
代码什么用20 分钟前
Spring基础使用
java·后端·spring
程序员老陆23 分钟前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光29 分钟前
C语言入门,深入理解指针(3)
c语言·开发语言
Su米苏43 分钟前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园1 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁1 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网1 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西2 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨2 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言