当前位置: 首页 > news >正文

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()枚举类的静态方法,返回当前枚举类的所有枚举类对象,返回值为当前枚举类对象数组

一般常用的是加粗的三个方法。

三、枚举类定义及解释

格式:

修饰符(如publicenum 枚举类名称{枚举类对象列表(一定要在枚举类最前面定义),属性,构造器,方法等等
}
如:
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、枚举类概念 类的对象只有有限个且确定的&#xff0c;这种类称之为枚举类&#xff1b;因为在jdk1.5之前没有enum关键字来定义枚举类&#xff0c;只能采用class定义一个类然后将类做一些修改满足对象个数有限且确定&#xff0c;那么这种类就是枚举类&#xf…...

SQL sever中的存储过程

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

spacy.load(“en_core_web_trf“)报错TypeError: issubclass() arg 1 must be a class

使用spacy时遇到的问题 写在最前面&#xff1a; 安装spacy和en_core_web_trf时需要保证二者版本一致 安装及查看对应spacy版本 安装 pip install spacy查看版本 import spacy spacy.__version__安装en_core_web_trf 直接安装&#xff08;如果可以的话&#xff09; pytho…...

【C++和数据结构】模拟实现哈希表和unordered_set与unordered_map

目录 一、哈希的概念与方法 1、哈希概念 2、常用的两个哈希函数 二、闭散列的实现 1、基本结构&#xff1a; 2、两种增容思路 和 插入 闭散列的增容&#xff1a; 哈希表的插入&#xff1a; 3、查找 4、删除 三、开散列的实现 1、基本结构 2、仿函数Hash 3、迭代器…...

十四天学会C++之第五天:类的详细讨论

1. 友元函数和友元类 什么是友元函数和友元类&#xff0c;它们的作用。如何声明和使用友元函数和友元类&#xff0c;访问类的私有成员。 友元函数&#xff08;Friend Functions&#xff09; 友元函数是一种特殊的函数&#xff0c;它被允许访问类的私有成员。这意味着即使成员…...

字典树学习笔记

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

web各个指标理解

QPS : 单位时间得请求次数 TPS &#xff1a;单位时间得事务数 并发 &#xff1a; QPS *单位响应时间 pv &#xff1a;进入一个网站&#xff0c;又单击打开该网站的其他页面&#xff0c;每打开一个页面就 增加一个PV,甚至在同一页面每刷新一次也多一个PV 二八定律&#xff1a;百…...

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命令&#xff0c;自动安装或更新包的时候&#xff0c;默认的镜像源服务器非常卡&#xff0c;很不方便。切换到国内的镜像源&#xff0c;下载更新非常快。为防止以后忘记&#xff0c;本文以国内服务器阿里巴巴的为例简单描述。 版本 Ubuntu23.10 找到更新…...

“一键合并剪辑,轻松添加片头——全新的视频编辑工具让你成为视频制作达人“

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

1.3 矩阵

一、向量与矩阵 下面是三个向量 u \boldsymbol u u、 v \boldsymbol v v、 w \boldsymbol w w&#xff1a; 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和互联网系统的发展&#xff0c;产生了越来越多的数据。数据量的积累带来了质的飞跃&#xff0c;使得数据应用从业务系统的一部分演变得愈发独立。物流、交通、新零售等越来越多的行业需要通过OLAP做到精细化运营&#xff0c;从而调控生产规则、运营效率、企…...

数二思维导图

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

ESXI6.5安装教程

设置从IPMI Virtual Disk 3000启动&#xff0c;出现如下界面&#xff1a; 默认选择第一项&#xff0c;回车安装 安装程序正在检测服务器硬件信息&#xff0c;如果不满足系统安装条件会跳出错误提示。 检测完成之后会出现下面界面 回车 按F11 这里列出了服务器硬盘信息&#…...

2023-9-25 美团售后服务系统后端一面【2024秋招】

1 实习 1.1 讲讲你做的一个需求&#xff0c;为什么这么做之类的 答&#xff1a; 1.2 什么是接线 1.3 什么的初始接线&#xff0c;和权威接线 答&#xff1a;初始接线是现状&#xff0c;权威是规划中的 1.4 为什么要做比较呢&#xff1f; 答&#xff1a;运维人员需要查看…...

YOLOv5改进实战 | GSConv + SlimNeck双剑合璧,进一步提升YOLO!

前言 轻量化网络设计是一种针对移动设备等资源受限环境的深度学习模型设计方法。下面是一些常见的轻量化网络设计方法: 网络剪枝:移除神经网络中冗余的连接和参数,以达到模型压缩和加速的目的。分组卷积:将卷积操作分解为若干个较小的卷积操作,并将它们分别作用于输入的不…...

Redis之zset在异步队列上的应用

当遇到并发的客户端请求时&#xff0c;为了缓解服务端的处理压力&#xff0c;当请求对响应的处理的实时性要求不高时&#xff0c;可以实现一个异步的请求消息队列。 一种实现策略是使用redis的zset&#xff0c;将消息的到期处理时间作为score&#xff0c;然后用多个线程去轮训…...

day4:Node.js 核心库

day4:Node.js 核心库 文章目录 day4:Node.js 核心库常用工具模块util 模块Moment 模块Lodash 模块web模块文件模块path 模块常用工具模块 Node.js有许多常用的工具,以下是一些常见的: util: 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的功能…...

PHP非对称与对称双向加密解密的方式

目录 RSA非对称加密解密&#xff1a; 什么是RSA非对称加密解密解析: 解析: 为什么使用: 有什么优点: DEMO: AES、DES、3DES等对称加密解密: 解析: 为什么使用: 有什么优点: DEMO: RSA非对称加密解密&#xff1a; 什么是RSA非对称加密解密解析: 解析: RSA非对称加密…...

机器学习:集成学习概念和分类、随机森林、Adaboost、GBDT

本文目录&#xff1a; 一、集成学习概念**核心思想&#xff1a;** 二、集成学习分类&#xff08;一&#xff09;Bagging集成&#xff08;二&#xff09;Boosting集成&#xff08;三&#xff09;两种集成方法对比 三、随机森林&#xff08;一&#xff09;构造过程&#xff08;二…...

【Java后端基础 005】ThreadLocal-线程数据共享和安全

&#x1f4da;博客主页&#xff1a;代码探秘者 ✨专栏&#xff1a;文章正在持续更新ing… ✅C语言/C&#xff1a;C&#xff08;详细版&#xff09; 数据结构&#xff09; 十大排序算法 ✅Java基础&#xff1a;JavaSE基础 面向对象大合集 JavaSE进阶 Java版数据结构JDK新特性…...

NoSQL 之Redis哨兵

目录 一、Redis 哨兵模式概述 &#xff08;一&#xff09;背景与核心目标 &#xff08;二&#xff09;基本架构组成 &#xff08;三&#xff09;核心功能 二、哨兵模式实现原理 &#xff08;一&#xff09;配置关键参数 &#xff08;二&#xff09;哨兵节点的定时任务 …...

Go 中的 Map 与字符处理指南

Go 中的 Map 与字符处理指南 在 Go 中&#xff0c;map 可以存储字符&#xff0c;但需要理解字符在 Go 中的表示方式。在 Go 语言中&#xff0c;"字符" 实际上有两种表示方法&#xff1a;byte&#xff08;ASCII 字符&#xff09;和 rune&#xff08;Unicode 字符&…...

Lifecycle 核心原理面试回答

1. 核心目标与设计思想 解耦生命周期管理&#xff1a; 将 Activity/Fragment 的生命周期回调逻辑从视图控制器中剥离&#xff0c;让业务组件&#xff08;如 Presenter, Repository 封装&#xff09;能独立感知生命周期。 状态驱动&#xff1a; 将离散的生命周期事件 (ON_CREAT…...

jenkins集成gitlab发布到远程服务器

jenkins集成gitlab发布到远程服务器 前面我们讲了通过创建maven项目部署在jenkins本地服务器&#xff0c;这次实验我们将部署在远程服务器&#xff0c;再以nginx作为前端项目做一个小小的举例 1、部署nginx服务 [rootweb ~]# docker pull nginx [rootweb ~]# docker images …...

Dify工具插件开发和智能体开发全流程

想象一下&#xff0c;你正在开发一个 AI 聊天机器人&#xff0c;想让它能实时搜索 Google、生成图像&#xff0c;甚至自动规划任务&#xff0c;但手动集成这些功能耗时又复杂。Dify 来了&#xff01;这个开源的 AI 应用平台让你轻松开发工具插件和智能体策略插件&#xff0c;快…...

CSS 平铺+自动换行效果

先上效果图 样式 <template><div class"activity-questions"><h1>活动题库</h1><div v-if"loading" class"loading">加载中...</div><div v-else><div v-if"questions.length 0" clas…...

飞牛使用Docker部署Tailscale 内网穿透教程

之前发过使用docker部署Tailscale的教程&#xff0c;不过是一年前的事情了&#xff0c;今天再重新发表一遍&#xff0c;这次使用compose部署更加方便&#xff0c;教程也会更加详细一点&#xff0c;希望对有需要的朋友有所帮助&#xff01; 对于大部分用户来说&#xff0c;白嫖 …...

Ubuntu 系统部署 MySQL 入门篇

一、安装 MySQL 1.1 更新软件包 在终端中执行以下命令&#xff0c;更新系统软件包列表&#xff0c;确保安装的是最新版本的软件&#xff1a; sudo apt update 1.2 安装 MySQL 执行以下命令安装 MySQL 服务端&#xff1a; sudo apt install mysql-server 在安装过程中&…...