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类的对象,违背了单一规则

    }
}
相关推荐
Sylvia-girl2 小时前
Java——抽象类
java·开发语言
Yana.nice4 小时前
Bash函数详解
开发语言·chrome·bash
Touper.5 小时前
Redis 基础详细介绍(Redis简单介绍,命令行客户端,Redis 命令,Java客户端)
java·数据库·redis
m0_535064606 小时前
C++模版编程:类模版与继承
java·jvm·c++
虾条_花吹雪6 小时前
Using Spring for Apache Pulsar:Message Production
java·ai·中间件
tomorrow.hello6 小时前
Java并发测试工具
java·开发语言·测试工具
Moso_Rx6 小时前
javaEE——synchronized关键字
java·java-ee
晓13137 小时前
JavaScript加强篇——第四章 日期对象与DOM节点(基础)
开发语言·前端·javascript
老胖闲聊7 小时前
Python I/O 库【输入输出】全面详解
开发语言·python
张小洛7 小时前
Spring AOP 是如何生效的(入口源码级解析)?
java·后端·spring