Java 枚举类
一、枚举类简介
1、枚举类概念
类的对象只有有限个且确定的,这种类称之为枚举类;因为在jdk1.5之前没有enum关键字来定义枚举类,只能采用class定义一个类然后将类做一些修改满足对象个数有限且确定,那么这种类就是枚举类;而在jdk1.5及之后就可以直接使用enum关键字来直接定义枚举类,这种方式比之前的方式更简单方便的定义枚举类且代码更明显分辨枚举类;同时是最安全的单例模式,可以避免new、反射、反序列化等方式创建对象破解单例。
2、枚举类使用场景及作用
由于枚举类的对象个数有限且确定的因此对于某些类似于订单状态、登录/支付/物流方式、审批状态、异常状态码与异常说明等等情况就很适合使用枚举类;这些场景如果直接使用常量等定义值不太好表示每种值的含义,只能通过常量名或注释等方式加以标注;而定义为枚举类则可以使用枚举类属性来表示这些值的含义,使代码更能方便解读;因此当 需要定义一组常量时,强烈建议使用枚举类进行定义 。
二、枚举类主要方法
注意:enum关键字定义的枚举类主要方法
方法名 | 作用说明 |
---|---|
valueOf(String name) | 传递枚举类对象名称name参数给静态方法valueOf,会得到与name参数匹配的枚举类对象(如:EnumAfter.valueOf(“DEVELOP”),如果name参数名称的枚举类对象不存在,则抛出 IllegalArgumentException 异常) |
public String toString() | 返回当前枚举类对象的名称,可以通过重写这个方法来使得到的结果更易读,比如重写为返回这个枚举类对象的具体属性信息(如:develop.toString()) |
public final boolean equals(Object other) | equals0方法是直接使用“==”实现的,并不是比较枚举类对象的值是否一致,它的存在是为了在Set、List 和 Map 中使用;由于equals方法是final修饰的因此该方法是不可变的,不能像toString()方法一样被重写 |
public final int hashCode() | Enum实现了hashCode()方法来和equals()保持一致;也是final修饰的也是不可变的,不能被重写 |
public final Class getDeclaringClass() | 获取枚举类对象的Class对象,和getClass()获取的结果类似 |
public final String name() | 获取当前枚举类对象在枚举类中声明的对象名称,建议优先使用未重写的toString()方法 |
public final int ordinal() | 获取枚举类对象在枚举类定义时枚举类中列举当前对象的序号(从0开始,0表示第一个列举的枚举类对象) |
public final int compareTo(E o) | 比较枚举类对象的大小,根据在定义枚举类时枚举类中声明的对象的先后顺序比较,比较结果是两个对象的 ordinal() 的值的差值(前一个对象的 ordinal() 的值减去后一个对象的 ordinal() 的值),需要比较的两个对象属于同一个枚举类的对象否则报错 |
values() | 枚举类的静态方法,返回当前枚举类的所有枚举类对象,返回值为当前枚举类对象数组 |
一般常用的是加粗的三个方法。
三、枚举类定义及解释
格式:
修饰符(如public) enum 枚举类名称{枚举类对象列表(一定要在枚举类最前面定义),属性,构造器,方法等等
}
如:
public enum Test {
}
示例:
package com.database.pool.testpool.enumtest;/*** 自定义枚举类及测试*/
public class EnumTest {public static void main(String[] args) {EnumBefor develop = EnumBefor.DEVELOP;//调用toString()方法的结果System.out.println("DEVELOP对象:"+develop);develop.common();System.out.println(develop.oneself());EnumAfter finance = EnumAfter.FINANCE;System.out.println("FINANCE对象:"+finance);//获取名称为DEVELOP的枚举类对象EnumAfter develop1 = EnumAfter.valueOf("DEVELOP");EnumAfter develop2 = EnumAfter.valueOf("DEVELOP");boolean equals = develop1.equals(develop2);//这里的比较结果是true,但枚举类的equals是采用的==作比较,那么比较的就是Java虚拟机栈的数据,也就是develop2和develop1这两个变量的引用地址做比较,由于他们指向的堆内存中的对象是同一个,所以地址一样System.out.println("equals比较结果:"+equals);//获取枚举类对象的hashCode值int hashCode = develop1.hashCode();System.out.println("hashCode结果:"+hashCode);//获取枚举类对象的Class对象Class<EnumAfter> declaringClass = develop1.getDeclaringClass();System.out.println("develop1的DeclaringClass:"+declaringClass);Class<? extends EnumAfter> aClass = develop1.getClass();System.out.println("develop1的Class:"+aClass);//获取枚举类对象名称(结果是枚举类中列举的枚举类对象的名称)System.out.println("枚举类对象名称name:"+develop1.name());//获取枚举类对象在枚举类定义时枚举类中列举当前对象的序号(从0开始,0表示第一个列举的枚举类对象)System.out.println("develop1枚举类对象在枚举类中声明时的序号:"+develop1.ordinal());//比较枚举类对象的大小,根据在定义枚举类时枚举类中声明的对象的先后顺序比较,比较结果是两个对象的 ordinal() 的值的差值(前一个对象的 ordinal() 的值减去后一个对象的 ordinal() 的值)System.out.println("compareTo比较结果:"+finance.compareTo(develop1));//获取某个枚举类的所有枚举类对象EnumAfter[] values = EnumAfter.values();for (EnumAfter value : values) {System.out.println("打印所有的枚举类对象:"+value);value.common();System.out.println(value.oneself());}/*** 如果enum类的属性不是final修饰的,并且提供set相关属性的方法,那么就可以对这个枚举类对象设置相关值,后续的finance1拿到的对象就是修改后的值* 此种情况对于enum来说一般是不允许的,因此enum类的属性需要定义为常量,并提供设置相关属性的构造器*//*finance.setName("xwcewc");System.out.println(finance);EnumAfter finance1 = EnumAfter.FINANCE;System.out.println(finance1);*/}}/*** jdk1.5之前没有enum关键字定义枚举方式* 枚举类:类的对象只有有限个且确定的,这种类称之为枚举类* 那么就需要做以下修改:* 1、对象数量有限意味着不能让使用者随意创建枚举类对象,那么需要私有化枚举类构造器* 2、对象数量有限且确定的,意味着需要列举出所有的枚举类对象并提供外部访问这些对象的入口(比如通过获取某个静态变量就是某个枚举类对象),并且由于对象是确定的意味着对象的属性不能修改,那么意味着枚举类的属性是private final修饰*/
class EnumBefor implements EnumInterface{/*** 属性是确定的不能做更改,所以需要final修饰定义为常量,那么就需要进行属性赋值但不能在此处声明时赋值,否则所有对象都一样,采用private final修饰属性* 此处不能赋值就必须拥有可以对该属性赋值的构造器否则报错*/private final String name;private final String desc;/*** 私有化构造器,由于属性是final,那么就需要对属性进行一次赋值,如果直接在属性声明时进行赋值那么所有的对象都一样了,所以作为构造器参数传入,每个对象一旦创建就不能更改* @param name* @param desc*/private EnumBefor(String name,String desc){this.name = name;this.desc = desc;}/*** 例举出枚举类的所有对象,并提供访问入口,使用public static final修饰*/public static final EnumBefor DEVELOP = new EnumBefor("开发部","程序开发"){/*** jdk1.5之前的方式对每个枚举类对象单独实现接口抽象方法,需要在枚举类中对所有抽象方法实现,然后每个枚举类对象单独实现自己逻辑的抽象方法,如果枚举类不对所有抽象方法实现,则会报错编译不通过* 如果枚举类对象不单独实现则调用该方法时使用枚举类对该抽象方法的实现逻辑* @return*/@Overridepublic String oneself() {return "1.5之前开发部单独实现!";}};public static final EnumBefor PERSONNEL = new EnumBefor("人事部","人力资源"){@Overridepublic String oneself() {return "1.5之前人事部单独实现!";}};public static final EnumBefor FINANCE = new EnumBefor("财务部","资金管理"){@Overridepublic String oneself() {return "1.5之前财务部单独实现!";}};public static final EnumBefor SELL = new EnumBefor("销售部","对外合作"){@Overridepublic String oneself() {return "1.5之前销售部单独实现!";}};/*** 提供访问属性的方法* @return*/public String getName() {return name;}public String getDesc() {return desc;}/*** 重写toString方法* @return*/@Overridepublic String toString() {return "EnumBefor{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}/*** 如果每个枚举类对象实现都是相同的逻辑,那么统一实现接口抽象方法即可*/@Overridepublic void common() {System.out.println("1.5之前公共的抽象方法实现!");}/*** 接口的所有抽象方法都必须实现,如果每个枚举类对象有单独实现抽象方法则生效单独实现的抽象方法* @return*/@Overridepublic String oneself() {return "1.5之前独占方法公共实现!";}
}/*** 定义接口及抽象方法*/
interface EnumInterface{void common();String oneself();
}/*** jdk1.5及之后直接采用enum关键字定义枚举类,这种方式是目前推荐和应该使用的方式* enum关键字定义的枚举类的父类是java.lang.Enum,因此枚举类对象的toString方法的结果不再是Object类的返回地址,而是返回当前对象的名称(比如这里的:DEVELOP、PERSONNEL、FINANCE、SELL)*/
enum EnumAfter implements EnumInterface{/*** enum要求将列举的枚举类对象放在类中最前面* 相比于1.5之前定义枚举类对象做以下修改由于所有对象都是public static final修饰的,因此修饰枚举类对象的public static final需要去掉* 并且对象类型都是当前枚举类所以EnumAfter需要去掉,且都是定义枚举类对象那么new的动作也需要去掉,并且多个对象之间用,隔开而不是;隔开且末尾用;* 这里虽然没有new这个代码,但实际上就是调用的拥有name和desc属性入参的构造器,因此下面需要定义一个这样的构造器,否则会报错* 本质是new创建一个对象,所以可以对每个枚举类对象单独实现方法*/DEVELOP("开发部","程序开发"){/*** 如果实现的抽象方法每个枚举类对象不一样,则在每个枚举类对象中单独实现接口抽象方法,如果抽象方法没有在枚举类中实现那么需要该抽象方法在每个枚举类对象中都单独实现否则报错编译不通过* 如果枚举类有实现抽象方法则枚举类对象可以不实现该抽象方法* 如果枚举类有实现且枚举类对象也有实现则枚举类对象的实现生效* @return*/@Overridepublic String oneself() {return "1.5之后开发部单独实现!";}},PERSONNEL("人事部","人力资源"){@Overridepublic String oneself() {return "1.5之后人事部单独实现!";}},FINANCE("财务部","资金管理"){@Overridepublic String oneself() {return "1.5之后财务部单独实现!";}},SELL("销售部","对外合作"){@Overridepublic String oneself() {return "1.5之后销售部单独实现!";}};/*** 枚举类的所有构造器都是private的,所以这个private可以省略* @param name* @param desc*/EnumAfter(String name,String desc){this.name = name;this.desc = desc;}/*** 属性是确定的不能做更改,所以需要final修饰定义为常量,那么就需要进行属性赋值但不能在此处声明时赋值,否则所有对象都一样,采用private final修饰属性* 此处不能赋值就必须拥有可以对该属性赋值的构造器否则报错* 如果不用final修饰,那么这个属性就是可变的,如果提供了set属性的方法且有人使用了set相关属性的方法那么会导致对象的值发生改变**/private final String name;private final String desc;/*** 获取相关属性的方法* @return*/public String getName() {return name;}public String getDesc() {return desc;}/*** 重写toString方法,否则toString方法是返回当前枚举类对象的名称* @return*/@Overridepublic String toString() {return "EnumAfter{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}/*** 根据name属性获取对应的枚举类对象,一般来说应当保证枚举类对象中name属性值的唯一性,否则获取的对象可能会有问题,所以name一般应当是状态码等的值,desc可以是状态值的说明* @param name* @return*/public static EnumAfter getInstanceByName(String name){if (null == name || name.trim().length() == 0){return null;}EnumAfter[] values = EnumAfter.values();for (EnumAfter value : values) {if (name.equals(value.name)){return value;}}return null;}/*** 如果每个枚举类对象实现都是相同的逻辑,那么统一实现接口抽象方法即可*/@Overridepublic void common() {System.out.println("1.5之后公共的抽象方法实现!");}/*** 如果枚举类对象有单独实现抽象方法,则采用单独实现的抽象方法的逻辑,枚举类没有实现的抽象方法必须每个枚举类对象单独实现否则报错编译不通过* 和1.5之前的枚举类定义不同的是1.5之前必须枚举类实现所有抽象方法,每个枚举类对象根据需要是否单独实现抽象方法,如果枚举类和枚举类对象都实现抽象方法枚举类对象的抽象方法生效* 1.5及之后则是要么枚举类实现要么枚举类对象实现二选一,如果两者都实现则枚举类对象实现的抽象方法逻辑生效** @return*/@Overridepublic String oneself() {return "1.5之后独占方法公共实现!";}
}
相关文章:

Java 枚举类
一、枚举类简介 1、枚举类概念 类的对象只有有限个且确定的,这种类称之为枚举类;因为在jdk1.5之前没有enum关键字来定义枚举类,只能采用class定义一个类然后将类做一些修改满足对象个数有限且确定,那么这种类就是枚举类…...

SQL sever中的存储过程
在Oracle的专篇中我也有仔细总结了存储过程的相关内容, 文章链接:http://t.csdnimg.cn/Z8AnH 尽管Oracle和SQL sever之间是存在一些区别,但许多基本的概念和原则在Oracle和SQL Server之间是通用的。它们之间有一些常见的区别,如下…...

spacy.load(“en_core_web_trf“)报错TypeError: issubclass() arg 1 must be a class
使用spacy时遇到的问题 写在最前面: 安装spacy和en_core_web_trf时需要保证二者版本一致 安装及查看对应spacy版本 安装 pip install spacy查看版本 import spacy spacy.__version__安装en_core_web_trf 直接安装(如果可以的话) pytho…...

【C++和数据结构】模拟实现哈希表和unordered_set与unordered_map
目录 一、哈希的概念与方法 1、哈希概念 2、常用的两个哈希函数 二、闭散列的实现 1、基本结构: 2、两种增容思路 和 插入 闭散列的增容: 哈希表的插入: 3、查找 4、删除 三、开散列的实现 1、基本结构 2、仿函数Hash 3、迭代器…...
十四天学会C++之第五天:类的详细讨论
1. 友元函数和友元类 什么是友元函数和友元类,它们的作用。如何声明和使用友元函数和友元类,访问类的私有成员。 友元函数(Friend Functions) 友元函数是一种特殊的函数,它被允许访问类的私有成员。这意味着即使成员…...

字典树学习笔记
trie 树,即字典树,是一种可以实现 O ( S ) O(S) O(S) 的预处理( S S S 为所有字符串的长度和), O ( N ) O(N) O(N)( N N N 为查询的字符串的长度)的查询的数据结构。 举个栗子,对于…...

web各个指标理解
QPS : 单位时间得请求次数 TPS :单位时间得事务数 并发 : QPS *单位响应时间 pv :进入一个网站,又单击打开该网站的其他页面,每打开一个页面就 增加一个PV,甚至在同一页面每刷新一次也多一个PV 二八定律:百…...
Java后端开发(七)-- 在gitee上部署远程仓库,通过idea上传本地代码(用idea2022版本开发)
目录 1. 在Gitee上创建gitee远程仓库 2.在打开idea,再打开您要上传的idea代码,先创建 本地git仓库...

Go语言入门心法(十二): GORM映射框架
Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 Go语言入门心法(六): HTTP面向客户端|服务端编程 Go语言入门心法(七): 并发与通道 Go语言入门心法(八): mysql驱动安装报错o…...

Ubuntu更新镜像源切换
概述 用ubuntu用apt命令,自动安装或更新包的时候,默认的镜像源服务器非常卡,很不方便。切换到国内的镜像源,下载更新非常快。为防止以后忘记,本文以国内服务器阿里巴巴的为例简单描述。 版本 Ubuntu23.10 找到更新…...

“一键合并剪辑,轻松添加片头——全新的视频编辑工具让你成为视频制作达人“
在日常生活中,我们时常会遇到需要制作视频的情况。但面对繁琐的视频剪辑和合并,你是否感到无从下手?今天,我们为你带来一款全新的视频编辑工具,让你轻松成为视频制作达人! 首先我们要进入好简单批量智剪主页…...

1.3 矩阵
一、向量与矩阵 下面是三个向量 u \boldsymbol u u、 v \boldsymbol v v、 w \boldsymbol w w: u [ 1 − 1 0 ] v [ 0 1 − 1 ] w [ 0 0 1 ] \boldsymbol u\begin{bmatrix}\,\,\,\,1\\-1\\\,\,\,\,0\end{bmatrix}\kern 10pt\boldsymbol v\begin{bmatrix}\,\,\,…...
阿里云-AnalyticDB【分析型数据库】总结介绍
一、背景 随着企业IT和互联网系统的发展,产生了越来越多的数据。数据量的积累带来了质的飞跃,使得数据应用从业务系统的一部分演变得愈发独立。物流、交通、新零售等越来越多的行业需要通过OLAP做到精细化运营,从而调控生产规则、运营效率、企…...

数二思维导图
高数上 第一章:函数、极限、连续 函数 函数的单调性、周期性、奇偶性复合函数 极限 求直接代入型的极限求∞∞型的极限用等价无穷小代换求00型的极限用洛必达法则求00型或∞∞型的极限求∞•0型的极限求幂指函数的极限函数的左右极限及需要求左右极限的情形极限的…...

ESXI6.5安装教程
设置从IPMI Virtual Disk 3000启动,出现如下界面: 默认选择第一项,回车安装 安装程序正在检测服务器硬件信息,如果不满足系统安装条件会跳出错误提示。 检测完成之后会出现下面界面 回车 按F11 这里列出了服务器硬盘信息&#…...
2023-9-25 美团售后服务系统后端一面【2024秋招】
1 实习 1.1 讲讲你做的一个需求,为什么这么做之类的 答: 1.2 什么是接线 1.3 什么的初始接线,和权威接线 答:初始接线是现状,权威是规划中的 1.4 为什么要做比较呢? 答:运维人员需要查看…...

YOLOv5改进实战 | GSConv + SlimNeck双剑合璧,进一步提升YOLO!
前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…...
Redis之zset在异步队列上的应用
当遇到并发的客户端请求时,为了缓解服务端的处理压力,当请求对响应的处理的实时性要求不高时,可以实现一个异步的请求消息队列。 一种实现策略是使用redis的zset,将消息的到期处理时间作为score,然后用多个线程去轮训…...
day4:Node.js 核心库
day4:Node.js 核心库 文章目录 day4:Node.js 核心库常用工具模块util 模块Moment 模块Lodash 模块web模块文件模块path 模块常用工具模块 Node.js有许多常用的工具,以下是一些常见的: util: 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的功能…...
PHP非对称与对称双向加密解密的方式
目录 RSA非对称加密解密: 什么是RSA非对称加密解密解析: 解析: 为什么使用: 有什么优点: DEMO: AES、DES、3DES等对称加密解密: 解析: 为什么使用: 有什么优点: DEMO: RSA非对称加密解密: 什么是RSA非对称加密解密解析: 解析: RSA非对称加密…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...

CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...