详解Java枚举为什么是单例模式的最佳选择
作者:不一样的科技宅 发布时间:2022-07-16 20:42:47
前言
单例模式,是工作中比较常见的一种设计模式,通常有两种实现方式,懒汉式和饿汉式。但是这两种实现方式存在一些问题。懒汉式需要在多线程环境下使用同步锁机制来保证只有一个实例被创建,这会影响程序的性能。而饿汉式在类加载时就创建实例,会导致程序在启动时变慢,同时也无法延迟实例的创建,这可能会浪费系统资源。所以今天介绍一下,为什么枚举是实现单例模式的最佳选择。
示例代码
public enum Singleton {
INSTANCE;
// 添加需要的实例变量和方法
private int count = 0;
public void incrementCount() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) {
Singleton singleton = Singleton.INSTANCE;
singleton.incrementCount();
System.out.println(singleton.getCount()); // 输出 1
Singleton anotherSingleton = Singleton.INSTANCE;
anotherSingleton.incrementCount();
System.out.println(anotherSingleton.getCount()); // 输出 2
System.out.println(singleton.getCount()); // 输出 2
}
}
在上面的示例中,Singleton 是一个枚举类型,其中声明了一个枚举常量 INSTANCE,它是单例模式的唯一实例。
该单例模式还可以拥有实例变量和方法,如上面的 count 实例变量和 incrementCount()、getCount() 方法。
通过运行上面的代码,我们可以看到 singleton 和 anotherSingleton 是同一个实例,因为它们都是通过 Singleton.INSTANCE 获取的,所以它们的计数器变量 count 是共享的,所以在 anotherSingleton 上调用 incrementCount() 方法后,singleton 上的 count 值也会被增加。
有哪些优点?
线程安全
使用枚举实现单例模式是线程安全的。在多线程环境中,多个线程可以同时访问单例对象,但是由于枚举的特殊性质,只有一个实例对象被创建,所以不会出现线程安全问题。
序列化安全
使用枚举实现单例模式可以避免序列化和反序列化的问题。在 Java 中,当一个类被序列化并在另一个 JVM 中反序列化时,它会创建一个新的对象。如果使用枚举实现单例模式,则不需要担心这个问题,因为枚举实例是在加载枚举类型时由 JVM 创建的,并且它们是全局可访问的,因此不会出现创建多个实例的情况。
防止反射攻击
使用枚举实现单例模式可以防止反射攻击。在 Java 中,反射机制可以通过 Class 类来获取对象的构造函数并创建新的对象。如果使用枚举实现单例模式,则可以避免这种攻击,因为枚举类型的构造函数是私有的,不能通过反射来调用。
简单明了可读性强
使用枚举实现单例模式可以使代码更加简洁明了。枚举类型本身就是单例的,因此不需要编写任何特殊的代码来实现单例模式。并且具有有意义的名称和明确定义的值,这可以减少代码量和提高代码的可读性。
来源:https://juejin.cn/post/7229660119658512441


猜你喜欢
- 前言应用系统需要通过Cache来缓存不经常改变得数据来提高系统性能和增加系统吞吐量,避免直接访问数据库等低速存储系统。缓存的数据通常存放在访
- 这篇文章主要介绍了springboot跨域CORS处理代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- using System;using System.Collections;using System.IO;namespace Consol
- public interface ArraySQL 类型 ARRAY 在 java 编程语言中的映射关系。默认情况下,Array 值是对 S
- 1.使用WIFI首先设置用户权限<uses-permission android:name="android.permiss
- Maven系列11.什么是Maven?Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生
- TCP与UDP都属于TCP/IP协议TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就
- VB.NET中的除法运算符有两个:/(浮点除法)、\(整数除法)C#中的除法运算符只有一个:/(除法)VB.NET中的除法运算符与C#中的除
- 假设下面是你的视频网站链接列表,如果别人想爬取你的数据十分轻松,看规则就知道数据库是序列自增的http://www.xxxx.com/vid
- PageAdapter是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即
- 生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试:一、在 .NET 中生成1、直
- 关于用户token处理到的坑当采用前后台完全分离,以微服务架构的搭建时。在搭建微服务过程中,由于每个服务都是独立的应用,这样就会造成一个统一
- 免责声明:本教程所有资源均来源于网络;仅用于学习交流,请勿用于任何商业行为;如需要,请使用正版授权;侵权联删。推荐最新 IntelliJ I
- 1. InputStream -> byte[]引入 apache.commons.is 包import org.apache.com
- 前言昨晚想在Android应用中增加一个int映射到String的字典表,使用HashMap实现的时候,Eclipse给出了一个警告,昨晚项
- RequestBody注解的List参数传递Controller方法参数:@RequestBody List<Long> ids
- Java的在还没有发现新写法之前时,我一直是这么初始化List跟Map://初始化List List&l
- 目录二维码生成原理(即工作原理)效果图如下:前提:源码如下:总结二维码生成原理(即工作原理)二维码官方叫版本Version。Version
- RabbitMQ作为AMQP的代表性产品,在项目中大量使用。结合现在主流的spring boot,极大简化了开发过程中所涉及到的消息通信问题
- 前言日常中,我们经常需要从浏览器中的网页或者从其它APP中直接打开我们的APP,我们就需要使用到深度链接技术。实现方式分别是 Dee pLi