Java枚举:为什么它是单例模式的最佳选择?

news2024/10/5 2:15:39

前言

  单例模式,是工作中比较常见的一种设计模式,通常有两种实现方式,懒汉式和饿汉式。但是这两种实现方式存在一些问题。懒汉式需要在多线程环境下使用同步锁机制来保证只有一个实例被创建,这会影响程序的性能。而饿汉式在类加载时就创建实例,会导致程序在启动时变慢,同时也无法延迟实例的创建,这可能会浪费系统资源。所以今天介绍一下,为什么枚举是实现单例模式的最佳选择。

示例代码

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 类来获取对象的构造函数并创建新的对象。如果使用枚举实现单例模式,则可以避免这种攻击,因为枚举类型的构造函数是私有的,不能通过反射来调用。

简单明了可读性强

  使用枚举实现单例模式可以使代码更加简洁明了。枚举类型本身就是单例的,因此不需要编写任何特殊的代码来实现单例模式。并且具有有意义的名称和明确定义的值,这可以减少代码量和提高代码的可读性。

总结

  首先,枚举实例是线程安全的,多线程环境下不会出现线程安全问题。其次,枚举实例由JVM创建的,可以避免序列化和反序列化的问题,并且它们是全局可访问的,也不会出现创建多个实例的情况。此外,枚举类型的构造函数是私有的,也可以防止反射攻击。所以说java枚举是实现单例模式的最佳选择。

结尾

  如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。

  我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/493465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《发展心理学——儿童与青少年》读书笔记

这是我读的第一本关于育儿教育类的书,该书的作者是David R. Shaffer,由北京师范大学博士生导师邹泓审校,由其底下的博士生们翻译。我看的是中文第九版。下面是我在阅读此书时做的关键摘录和部分感想: 第1章 导论:发展心理学及其研…

Java基础(二十一):集合源码

Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)&#xff1…

耗时2.5h含泪打造windows10家庭版docker安装

文章目录 一、事出有因二、安装流程Problem1Problem2Problem3 三、胜利的曙光 一、事出有因 由于最近需要跑通github上的一个代码,那个github上的代码需要通过docker部署到本地,但是我的电脑上并没有docker,真的是含泪历时2.5h才把docker在我的windows电…

【Python成长之路】基于Flask-admin库,结合html+vue,实现前后端数据传递

一、前言 前面已经做了Flask-admin库的基本介绍和几个库常用功能如何使用,若不了解请移步到以下博客: 1、?《【Python成长之路】基于Flask-admin库,编写个人工作平台代码详述》 2、?《【Python成长之路】基于Flask-admin库,编…

DP练习题

1.减操作(ACWING) 若有 a b c d e f g 几个数, 先对位置d操作 变成 a b c d - e f g 再对c操作 变成 a b c - (d-e) f g 仔细分析后得出结论:对于第一个数如a, 它一定为正数,第二个数b,一定为负数&#…

Java并发(四)----线程运行原理

1、线程运行原理 1.1 栈与栈帧   Java Virtual Machine Stacks (Java 虚拟机栈 JVM) 我们都知道 JVM 中由堆、栈、方法区所组成,其中栈内存是给谁用的呢?其实就是线程,每个线程启动后,虚拟机就会为其分…

java 解密springboot的WEB端口是谁启动的之内嵌tomcat

找到项目的 pom.xml 看到下面的spring-boot-starter-web 我们按住 Ctrl 点击进去 里面就有一个 tomcat 简单说 我们的程序能启动起tomcat端口 就是靠的这个东西 简单说 就是在程序中嵌了一个tomcat服务器 这里 可能就有小伙伴蒙了 不是把程序放在服务器上运行吗&#xff1f…

Linux Driver 和Device匹配过程分析(2)

Linux Driver 和Device匹配过程分析(2) 1 device注册流程2,driver注册匹配过程:2.1 pci_register_driver2.1.1 nvme_init2.1.2 pci_register_driver2.1.3 __pci_register_driver2.1.4 driver_register2.1.5 bus_add_driver2.1.6 d…

读书笔记——《2001太空漫游》

阿瑟克拉克神作,任何一个科幻迷都绕不开的一部作品。很早就听说过其大名,因为之前看过电影版的,总感觉少了点新鲜感,这本书就一直在书架上没有拿出来看。但是看过这本书后,我可以很负责任的说,全书都充满新…

【递推专题】常见的递推“模型”总结

目录 1.斐波那契数列分析:代码: 2.平面分割问题分析: 3.汉诺塔问题分析: 4.卡特兰数分析: 5.第二类斯特林数总结: 1.斐波那契数列 分析: 斐波那契数列又称兔子数列,其原理来源于兔子…

dangerousRemoteUrlIpcAccess

问题描述: 在使用Tauri窗口加载外部链接时,需要也能继续使用Tauri API与Rust交互。按照官方发布通告中的代码添加配置: "security": {"dangerousRemoteUrlIpcAccess": [ { "windows": ["main", &qu…

在Linux中进行Jenkins部署(maven-3.9.1+jdk8)

Jenkins部署在公网IP为x.x.x.x的服务器上 maven-3.9.1要安装在jdk8环境中 环境准备 第一步,下载server-jre-8u202-linux-x64.tar.gz安装包。 登录地址:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html下载server-j…

Maven命令和配置详解

Maven命令和配置详解 1. pom基本结构2. build基本结构3. Maven命令详解3.1 打包命令3.2 常用命令3.3 批量修改版本-父子pom4. Maven配置详解4.1 settings.xml4.2 项目内的maven工程结构Maven POM构建生命周期工程实践1. pom基本结构 <?xml versi

《程序员面试金典(第6版)》面试题 16.13. 平分正方形(直线的斜截式方程,C++)

题目描述 给定两个正方形及一个二维平面。请找出将这两个正方形分割成两半的一条直线。假设正方形顶边和底边与 x 轴平行。 每个正方形的数据square包含3个数值&#xff0c;正方形的左下顶点坐标[X,Y] [square[0],square[1]]&#xff0c;以及正方形的边长square[2]。所求直线穿…

JDK8 中Arrays.sort() 排序方法解读

一、引言 在刷算法的时候经常需要对数组进行排序&#xff0c;第一反应就是直接使用java.util包下的Arrays.sort()方法直接排序。但在刷算法时会通过时间复杂度和空间复杂度对实现的算法进行评价&#xff0c;因此我们需对Arrays.sort()方法有所了解。 本文先行介绍Arrays.sort…

图的基本概念和术语

图&#xff1a;G&#xff08;V,E&#xff09; V:顶点&#xff08;数据元素&#xff09;的又穷非空集合&#xff1b; E:边的有穷集合。 无向图&#xff1a;每条边都是无方向的G2 有向图&#xff1a; 每条边都是有方向的G1 完全图&#xff1a;任意两个点都有一条边相连 假设…

使用rollup打包ts+react缓存组件发布npm

新建一个项目目录比如叫root,下面新建一个rollup的配置文件: rollup.config.ts 因为rollup良好支持ts和esmodule 所以用ts配置文件 Setup 生成一个package.json文件,这里用pnpm生成: pnpm init安装rollup和Typescript: pnpm add rollup pnpm add typescript配置package.jso…

Android 自定义View 之 简易输入框

简易输入框 前言正文① 构造方法② XML样式③ 测量④ 绘制1. 绘制方框2. 绘制文字 ⑤ 输入1. 键盘布局2. 键盘接口3. 键盘弹窗4. 显示键盘5. 相关API 四、使用自定义View五、源码 前言 在日常工作开发中&#xff0c;我们时长会遇到各种各样的需求&#xff0c;不部分需求是可以通…

在云服务器上部署jupyter服务

1.准备一台云服务器&#xff0c;阿里云、腾讯云都可以&#xff0c;并且远程登陆&#xff0c;在云服务器的安全组中配置8888的访问端口&#xff0c;因为jupyter默认的访问端口是8888&#xff0c;如下述步骤&#xff1b;以阿里云服务器的centos系统为例 2.使用以下命令在服务器…

golang 微服务容错处理是如何做的?

随着微服务的规模越来越大&#xff0c;各个微服务之间可能会存在错综复杂的调用关系 在我们实际工作中&#xff0c;确实慢慢的也出现了很多问题&#xff0c;整个系统的弊端的慢慢的展现出来 例如就会有这样的情况&#xff1a; 服务 A 去请求服务B&#xff0c;服务 B 还需要去…