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

    }
}
相关推荐
Fireworkitte2 小时前
Apache POI 详解 - Java 操作 Excel/Word/PPT
java·apache·excel
weixin-a153003083162 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
DCTANT3 小时前
【原创】国产化适配-全量迁移MySQL数据到OpenGauss数据库
java·数据库·spring boot·mysql·opengauss
Touper.3 小时前
SpringBoot -- 自动配置原理
java·spring boot·后端
黄雪超3 小时前
JVM——函数式语法糖:如何使用Function、Stream来编写函数式程序?
java·开发语言·jvm
ThetaarSofVenice3 小时前
对象的finalization机制Test
java·开发语言·jvm
思则变3 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
GodKeyNet4 小时前
设计模式-模板模式
设计模式·模板模式
lijingguang4 小时前
在C#中根据URL下载文件并保存到本地,可以使用以下方法(推荐使用现代异步方式)
开发语言·c#
¥-oriented4 小时前
【C#中路径相关的概念】
开发语言·c#