【Java 数据结构】枚举
枚举的使用
- 1 背景及定义
- 2 使用
- 3 枚举优点缺点
- 4 枚举和反射
- 4.1 枚举是否可以通过反射,拿到实例对象呢?
- 5 总结
- 面试问题(单例模式学完后可以回顾):
1 背景及定义
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLACK = 3;
但是常量举例有不好的地方,例如:可能碰巧有个数字1,但是他有可能误会为是RED,现在我们可以直接用枚举
来进行组织,这样一来,就拥有了类型,枚举类型。而不是普通的整形1.
public enum TestEnum {RED,BLACK,GREEN;
}
优点:将常量组织起来统一进行管理
场景:错误状态码,消息类型,颜色的划分,状态机等等…
本质:是 java.lang.Enum 的子类,也就是说,自己写的枚举类,就算没有显示的继承 Enum ,但是其默认继承了这个类。
2 使用
1、switch语句
public enum TestEnum {
RED,BLACK,GREEN,WHITE;
public static void main(String[] args) {
TestEnum testEnum2 = TestEnum.BLACK;switch (testEnum2) {case RED:System.out.println("red");break;case BLACK:System.out.println("black");break;case WHITE:System.out.println("WHITE");break;case GREEN:System.out.println("black");break;default:break;}
}
}
2、常用方法
Enum 类的常用方法

示例一:
public enum TestEnum {RED,BLACK,GREEN,WHITE;public static void main(String[] args) {TestEnum[] testEnum2 = TestEnum.values();for (int i = 0; i < testEnum2.length; i++) {System.out.println(testEnum2[i] + " " + testEnum2[i].ordinal());}System.out.println("=========================");System.out.println(TestEnum.valueOf("GREEN"));}
}
示例二:
public enum TestEnum {RED,BLACK,GREEN,WHITE;public static void main(String[] args) {//拿到枚举实例BLACKTestEnum testEnum = TestEnum.BLACK;//拿到枚举实例REDTestEnum testEnum21 = TestEnum.RED;System.out.println(testEnum.compareTo(testEnum21));System.out.println(BLACK.compareTo(RED));System.out.println(RED.compareTo(BLACK));}
}
刚刚说过,在Java当中枚举实际上就是一个类。所以我们在定义枚举的时候,还可以这样定义和使用枚举:
重要:枚举的构造方法默认是私有的
public enum TestEnum {RED("red",1),BLACK("black",2),WHITE("white",3),GREEN("green",4);private String name;private int key;/*** 1、当枚举对象有参数后,需要提供相应的构造函数* 2、枚举的构造函数默认是私有的 这个一定要记住* @param name* @param key*/private TestEnum (String name,int key) {this.name = name;this.key = key;}public static TestEnum getEnumKey (int key) {for (TestEnum t: TestEnum.values()) {if(t.key == key) {return t;}}return null;}public static void main(String[] args) {System.out.println(getEnumKey(2));}
}
3 枚举优点缺点
优点:
- 枚举常量更简单安全 。
- 枚举具有内置方法 ,代码更优雅
缺点:
- 不可继承,无法扩展
4 枚举和反射
4.1 枚举是否可以通过反射,拿到实例对象呢?
我们刚刚在反射里边看到了,任何一个类,哪怕其构造方法是私有的,我们也可以通过反射拿到他的实例对象,那么枚举的构造方法也是私有的,我们是否可以拿到呢?接下来,我们来实验一下:
public enum TestEnum {RED("red",1),BLACK("black",2),WHITE("white",3),GREEN("green",4);private String name;private int key;/*** 1、当枚举对象有参数后,需要提供相应的构造函数* 2、枚举的构造函数默认是私有的 这个一定要记住* @param name* @param key*/private TestEnum (String name,int key) {this.name = name;this.key = key;}public static TestEnum getEnumKey (int key) {for (TestEnum t: TestEnum.values()) {if(t.key == key) {return t;}}return null;}public static void reflectPrivateConstructor() {try {Class<?> classStudent = Class.forName("TestEnum");//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类是提供了两个参数分别是String和int。Constructor<?> declaredConstructorStudent = classStudent.getDeclaredConstructor(String.class,int.class);//设置为true后可修改访问权限declaredConstructorStudent.setAccessible(true);Object objectStudent = declaredConstructorStudent.newInstance("绿色",666);TestEnum testEnum = (TestEnum) objectStudent;System.out.println("获得枚举的私有构造函数:"+testEnum);} catch (Exception ex) {ex.printStackTrace();}}public static void main(String[] args) {reflectPrivateConstructor();}
}
输出结果:
java.lang.NoSuchMethodException: TestEnum.(java.lang.String, int)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at TestEnum.reflectPrivateConstructor(TestEnum.java:40)
at TestEnum.main(TestEnum.java:54)
老铁们啊,看到没有哇!异常信息是: java.lang.NoSuchMethodException: TestEnum.(java.lang.String, int) ,什么意思是:就是没有对应的构造方法,我的天呐!我们提供的枚举的构造方法就是两个参数分别是 String 和 int啊!!!!问题出现在哪里呢?还记不记得我们说过的,我们所有的枚举类,都是默认继承与 java.lang.Enum ,说到继承,继承了什么?继承了父类除构造函数外的所有东西,并且子类要帮助父类进行构造!而我们写的类,并没有帮助父类构造!那意思是,我们要在自己的枚举类里面,提供super吗?不是的,枚举比较特殊,虽然我们写的是两个,但是默认他还添加了两个参数,哪两个参数呢?我们看一下Enum类的源码:
protected Enum(String name, int ordinal) {this.name = name;this.ordinal = ordinal;
}
也就是说,我们自己的构造函数有两个参数一个是String一个是int,同时他默认后边还会给两个参数,一个是
String一个是int。也就是说,这里我们正确给的是4个参数:
public static void reflectPrivateConstructor() {try {Class<?> classStudent = Class.forName("TestEnum");//注意传入对应的参数,获得对应的构造方法来构造对象,当前枚举类是提供了两个参数分别是String和int。Constructor<?> declaredConstructorStudent =classStudent.getDeclaredConstructor(String.class,int.class,String.class,int.class);//设置为true后可修改访问权限declaredConstructorStudent.setAccessible(true);//后两个为子类参数,大家可以将当前枚举类的key类型改为double验证Object objectStudent = declaredConstructorStudent.newInstance("父类参数",666,"子类参数",888);TestEnum testEnum = (TestEnum) objectStudent;System.out.println("获得枚举的私有构造函数:"+testEnum);} catch (Exception ex) {ex.printStackTrace();}
}
此时运行程序结果是:\
java.lang.IllegalArgumentException: Cannot reflectively create enum objects
at java.lang.reflect.Constructor.newInstance(Constructor.java:416)
at TestEnum.reflectPrivateConstructor(TestEnum.java:46)
at TestEnum.main(TestEnum.java:55)
嗯!没错,他还报错了,不过这次就是我想要的结果!此时的异常信息显示,是我的一个方法这个方法是:
newInstance() 报错了!没错,问题就是这里,我们来看一下这个方法的源码,为什么会抛出
java.lang.IllegalArgumentException: 异常呢?
源码显示:

是的,枚举在这里被过滤了,你不能通过反射获取枚举类的实例!这道题是2017年阿里巴巴曾经问到的一个问
题,不看不知道,一看吓一跳!同学们记住这个坑。**原版问题是:为什么枚举实现单例模式是安全的?**希望同学们记住这个问题!
5 总结
1、枚举本身就是一个类,其构造方法默认为私有的,且都是默认继承与 java.lang.Enum
2、枚举可以避免反射和序列化问题
3、枚举的优点和缺点
面试问题(单例模式学完后可以回顾):
后面博主在多线程时会讲到单例模式
1、写一个单例模式。
public class Singleton {private volatile static Singleton uniqueInstance;private Singleton() {}public static Singleton getInstance() {if (uniqueInstance == null) {synchronized (Singleton.class){if(uniqueInstance == null){//进入区域后,再检查一次,如果仍是null,才创建实例uniqueInstance = new Singleton();}}}return uniqueInstance;}
}
2、用静态内部类实现一个单例模式
博主之前讲过各种内部类(包扩静态内部类),大家可以去翻翻之前的博客看一下
class Singleton {/** 私有化构造器 */private Singleton() {}/** 对外提供公共的访问方法 */public static Singleton getInstance() {return UserSingletonHolder.INSTANCE;}/** 写一个静态内部类,里面实例化外部类 */private static class UserSingletonHolder {private static final Singleton INSTANCE = new Singleton();}
}
public class Main {public static void main(String[] args) {Singleton u1 = Singleton.getInstance();Singleton u2 = Singleton.getInstance();System.out.println("两个实例是否相同:"+ (u1==u2));}
}
3、用枚举实现一个单例模式
public enum TestEnum {INSTANCE;public TestEnum getInstance(){return INSTANCE;
}public static void main(String[] args) {TestEnum singleton1=TestEnum.INSTANCE;TestEnum singleton2=TestEnum.INSTANCE;System.out.println("两个实例是否相同:"+(singleton1==singleton2));}
}
相关文章:
【Java 数据结构】枚举
枚举的使用 1 背景及定义2 使用3 枚举优点缺点4 枚举和反射4.1 枚举是否可以通过反射,拿到实例对象呢? 5 总结面试问题(单例模式学完后可以回顾): 1 背景及定义 public static final int RED 1; public static final int GREEN 2; public …...
Python(20)正则表达式(Regular Expression)中常用函数用法
大家好!我是码银🥰 欢迎关注🥰: CSDN:码银 公众号:码银学编程 正文 正则表达式 粗略的定义:正则表达式是一个特殊的字符序列,帮助用户非常便捷的检查一个字符串是否符合某种模…...
docker 离线安装镜像
一、导出镜像 下载完镜像后,我们需要将其导出为tar文件,以便在离线环境中使用。 执行以下命令导出镜像: docker save -o <保存路径>/<镜像名>_<版本>.tar <镜像名>:<版本>其中,<保存路径>是…...
由vscode自动升级导致的“终端可以ssh服务器,但是vscode无法连接服务器”
问题描述 简单来说就是,ssh配置没动,前两天还可以用vscode连接服务器,今天突然就连不上了,但是用本地终端ssh可以顺利连接。 连接情况 我的ssh配置如下: Host gpu3HostName aaaUser zwx现在直接在终端中进行ssh&am…...
typecho 在文章中添加 bilibili 视频
一、获取视频来源: 可以有2种方式来定位一个 bilibili 视频: 第一种是使用 bvid 参数定位第二种是使用 aid 参数定位 如何获取这两个参数? 首先我们可以看看 bilibili 网站中的视频页面链接其实可以分为两种: 第一种是类似&a…...
Android.mk 语法详解
一.Android.mk简介 Android.mk 是Android 提供的一种makefile 文件,注意用来编译生成(exe,so,a,jar,apk)等文件。 二.Android.mk编写 分析一个最简单的Android.mk LOCAL_PATH : $(call my-dir) //定义了…...
ChatGPT高效提问—prompt基础
ChatGPT高效提问—prompt基础 设计一个好的prompt对于获取理想的生成结果至关重要。通过选择合适的关键词、提供明确的上下文、设置特定的约束条件,可以引导模型生成符合预期的回复。例如,在对话中,可以使用明确的问题或陈述引导模型生成…...
Elasticsearch 中的索引的分区(Shards)和副本(Replicas)的使用
Elasticsearch是一个高性能的、分布式的搜索与数据分析引擎,广泛用于全文搜索、结构化搜索、分析以及这三者的组合场景。在Elasticsearch中,“索引”(Index)是其最基本的数据管理单位,可以类比为传统关系数据库中的“数…...
智慧工地反光衣识别检测系统-自动识别是否穿着制定工作服---豌豆云
智慧工地反光衣识别检测特定地区工作人员不穿反光服装个人行为预警,一旦检测到某些不穿反光服装施工作业人员智慧工地反光衣识别检测马上开启警报。 真真正正做到事前预警、事中检测、过后管理。安全操作规程工作人员从繁杂无趣的盯显示屏的每日任务中抽身出去。 …...
vue绘制语音波形图---wavesurfer.js
文章目录 创建实例optionsmethod接收Blob流 https://wavesurfer.xyz/ 创建实例 引入插件:import WaveSurfer from "wavesurfer.js"创建实例对象:this.wavesurfer WaveSurfer.create(options); <div id"waveform"><!-- t…...
MPLS——多协议标签交换
目录 1 多协议标签交换 MPLS 1.1 MPLS 的工作原理 1.1.1 MPLS 工作特点 1.1.2 MPLS 协议的基本原理 1.1.3 MPLS 的基本工作过程 1.2 转发等价类 FEC 1.2.1 FEC 用于负载平衡 1.3 MPLS 首部的位置与格式 1.3.1 MPLS 首部的位置 1.3.2 MPLS 首部的格式 1.4 新一代的…...
Idea使用Lombok失效解决方案
问题描述 启动项目时,使用lombok插件中slf4g注解后其中的log显示找不到变量 解决方案 在以下位置加入该配置-Djps.track.ap.dependenciesfalse Preferences | Build, Execution, Deployment | Compiler 之后保存应用就好,亲测有效。...
Java实现网上药店系统 JAVA+Vue+SpringBoot+MySQL
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 药品类型模块2.3 药品档案模块2.4 药品订单模块2.5 药品收藏模块2.6 药品资讯模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 药品表3.2.3 药品订单表3.2.4 药品收藏表3.2.5 药品留言表…...
谁是嫌疑犯问题
问题描述: 有6名犯罪嫌疑人A、B、C、D、E、F,已知如下事实: A、B至少有1人作案; A、E、F三人中至少有2人参与作案; A、D不可能是同案犯; B、C或同时作案,或与本案无关; C、D中…...
Netty中使用编解码器框架
目录 什么是编解码器? 解码器 将字节解码为消息 将一种消息类型解码为另一种 TooLongFrameException 编码器 将消息编码为字节 将消息编码为消息 编解码器类 通过http协议实现SSL/TLS和Web服务 什么是编解码器? 每个网络应用程序都必须定义如何…...
【漏洞复现】斐讯FIR151M路由器未授权下载漏洞
Nx01 产品简介 斐讯数据通信技术有限公司成立于2009年,是为用户提供智慧家庭领域智能产品和云服务的科技创新性企业。 Nx02 漏洞描述 斐讯 FIR151M路由器配置文件未授权下载漏洞,攻击者可利用该漏洞获取敏感信息。 Nx03 产品主页 fofa-query: app"PHICOMM-F…...
【SpringBoot】application配置(5)
type-aliases-package: com.rabbiter.cm.domaintype-aliases-package: 这个配置用于指定mybatis的别名,别名是一个简化的方式,让你在Mapper xml 文件中引用java类型,而不需要使用使用完整的类名。例如,如果你在 com.rabbiter.cm.d…...
Linux安全技术与iptables防火墙
一.安全技术: 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报警和事后监督为主,提供有针对性的指导措施和安全决策依据,…...
QT QCombox 样式表 比起作用
对QCombox在ui编辑器中进行美化,发现外表美化有效果,但下拉框的高度美化的没效果,查看样式表也没有没问题,样式表中内容如下。 QComboBox#curve_comboBox {min-width: 150px;min-height:40;max-width: 150px;max-height:40;borde…...
在 Windows 10 上使用 Visual Studio 2022 进行 C++ 桌面开发
工具下载链接:https://pan.quark.cn/s/c70b23901ccb 环境介绍 在今天的快速发展的软件开发行业中,选择合适的开发环境是非常关键的一步。对于C开发人员来说,Visual Studio 2022(VS2022)是一个强大的集成开发环境&…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
