Java设计模式中的创建者模式/单例模式是啥?单例模式其中的饿汉式与懒汉式又是啥?又可以用在哪些地方
- 开源代码
- 2025-08-20 19:21:02

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!
4. 创建者模式 4.1 特点 使用者不需要知道对象的创建细节 4.2 单例模式 4.2.1使用场景 单例类:且仅能创建一个实例类访问类:使用单例类 4.2.2 创建方式 4.2.2.1 饿汉式 类加载时就会创建单例对象存在内存浪费问题静态成员变量 public class SingletonDemo1 { //私有构造函数 private SingletonDemo1(){} //类中创建对象 private static SingletonDemo1 instance = new SingletonDemo1(); //提供访问方式,让外界获取 public static SingletonDemo1 getInstance(){ return instance; } }测试代码,结果为true
// 获取对象 SingletonDemo1 singletonDemo1 =SingletonDemo1.getInstance(); SingletonDemo1 singletonDemo2 =SingletonDemo1.getInstance(); // 判断是否一样 System.out.println(singletonDemo1 == singletonDemo2); } 静态代码块,测试类似,结果依旧为true public class SingletonDemo2 { //私有构造函数 private SingletonDemo2(){} //类中创建对象 private static SingletonDemo2 instance ; // 静态代码块赋值对象 static { instance = new SingletonDemo2(); } //提供访问方式,让外界获取 public static SingletonDemo2 getInstance(){ return instance; } } 4.2.2.2 懒汉式 使用对象时才创建对象线程不安全方式,测试代码类似,单线程结果为true,多线程为false public class SingletonDemo3 { //私有构造函数 private SingletonDemo3(){} //类中创建对象 private static SingletonDemo3 instance ; public static SingletonDemo3 getInstance(){ // 若instance为null,则未创建,创建新对象,否则返回instance if(instance == null) instance = new SingletonDemo3(); return instance; } } 线程安全式,代码仅仅一点改动,测试代码类似,单线程多线程均为true,但执行效率低 //和之前一样 public static synchronized SingletonDemo3 getInstance(){ // 若instance为null,则未创建,创建新对象,否则返回instance if(instance == null) instance = new SingletonDemo3(); return instance; } 双重检查锁式,解决效率低下问题,但在多线程下可能会空指针,原因是JVM在实例化对象中会进行优化和指令重排序 //和之前一样 public static SingletonDemo4 getInstance(){ // 若第一次判断instance不为null,不需要抢占锁,直接返回instance if(instance == null) { synchronized (SingletonDemo4.class) { // 第二次判断 if(instance == null) instance = new SingletonDemo4(); } } return instance; }改进则是加volatile,比较推荐使用,如图
静态内部类,JVM加载外部类时不加载静态内部类,只有内部类属性/方法被调用时才会被加载并初始化静态属性结果为true public class SingletonDemo5 { //私有构造函数 private SingletonDemo5(){} //类中创建对象 private static class Singleton{ private static final SingletonDemo5 INSTANCE = new SingletonDemo5(); } //提供访问方式,让外界获取 public static SingletonDemo5 getInstance(){ return Singleton.INSTANCE; } } 4.2.2.3 枚举式(恶汉式) 4.2.2.3.1 特点线程安全,只会装载一次,书写简单,唯一一种不会被破坏掉的方式
4.2.2.3.2 代码 public enum SingletonDemo6 { INSTANCE; }测试类似,结果为true
4.2.3 存在问题 4.2.3.1 问题会破坏单例模式唯一性
4.2.3.2 序列化及反序列化 源代码 public class SingletonDemo7 implements Serializable { //私有构造函数 private SingletonDemo7(){} //类中创建对象 private static SingletonDemo7 instance = new SingletonDemo7(); //提供访问方式,让外界获取 public static SingletonDemo7 getInstance(){ return instance; } } 测试代码,结果两者显示不一样,不是唯一对象,破坏单例模式 public static void readObject() throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./a.txt")); SingletonDemo7 singletonDemo1 = (SingletonDemo7) objectInputStream.readObject(); System.out.println(singletonDemo1); objectInputStream.close(); } public static void writeObject() throws Exception { ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./a.txt")); outputStream.writeObject(SingletonDemo7.getInstance()); outputStream.close(); } public static void main(String[] args) throws Exception { // writeObject(); readObject(); readObject(); } 4.2.3.3 反射 源代码使用懒汉式静态成员变量代码测试代码 public static void main(String[] args) throws Exception { // 获取Singleton的字节码对象 Class clas = SingletonDemo1.class; // 获取无参构造函数对象 Constructor declaredConstructors = clas.getDeclaredConstructor(); // 取消访问检查 declaredConstructors.setAccessible(true); // 创建singleton对象 SingletonDemo1 o = (SingletonDemo1) declaredConstructors.newInstance(); SingletonDemo1 o1 = (SingletonDemo1) declaredConstructors.newInstance(); System.out.println(o == o1); } 4.2.3.4 解决办法 4.2.3.4.1 序列化与反序列化 在Singleton类中添加readsolve()方法如图 4.2.3.4.2 反射 加boolean 判断如图 4.2.4 Runtime 4.2.4.1 特点 使用单例模式来进行对象创建具体是饿汉式的静态成员变量,如图 4.2.4.2 简单使用 测试代码 public static void main(String[] args) throws Exception { // 获取对象 Runtime runtime = Runtime.getRuntime(); // 执行控制台命令 ipconfig Process process = runtime.exec("ipconfig"); // 获取文件输入流 InputStream inputStream = process.getInputStream(); // 创建字节数组接收 byte[] bytes = new byte[1024*1024*100]; // 获取最终长度 int read = inputStream.read(bytes); // 将字节数组转换为字符串 System.out.println(new String(bytes,0,read,"GBK")); } 结果Java设计模式中的创建者模式/单例模式是啥?单例模式其中的饿汉式与懒汉式又是啥?又可以用在哪些地方由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java设计模式中的创建者模式/单例模式是啥?单例模式其中的饿汉式与懒汉式又是啥?又可以用在哪些地方”
上一篇
webpack基本使用
下一篇
记一次靶场实战【网络安全】