Java枚举中定义属性

article/2025/9/27 11:00:53

文章目录

  • 1、复习枚举
  • 2、自定义属性
  • 3、自定义属性枚举类和常量的对比
  • 4、常用方法
  • 5、枚举自定义属性在开发中的应用:字典表
  • 6、补充:入参校验

刚接触枚举时的例子太简单,就一个Season枚举类,里面四个常量值,后来开发中看到枚举中定义属性就很看不惯。这里梳理下Java枚举中定义属性,以及枚举在开发中的实际应用举例。

1、复习枚举

  • Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一年的 12 个月份
  • Java枚举类使用enum定义,各个常量之间用逗号分隔
enum Color 
{ RED, GREEN, BLUE; 
} 
  • 枚举类中引用每一个常量值,用类名.常量
public class Test
{public static void main(String[] args){Color c1 = Color.RED;System.out.println(c1);}
}//输出RED
  • 初学时的经典例子,和switch连用
public class MyClass {public static void main(String[] args) {Color myVar = Color.BLUE;switch(myVar) {case RED:System.out.println("红色");break;case GREEN:System.out.println("绿色");break;case BLUE:System.out.println("蓝色");break;}}
}
//蓝色
  • 内部类中使用枚举
public Class MyDemo{enum Color{RED, GREEN, BLUE;}public void doSome(){....}}

2、自定义属性

枚举类的语法结构虽然和普通类不一样,但是经过编译器之后产生的也是一个class文件。该class文件再反编译回来可以看到实际上是生成了一个类。该类继承了java.lang.Enum<E>,且所有的枚举值都是 public static final 的,以上枚举类Color可理解为:

//java为单继承,因此不能再继承其他类
class Color extends java.lang.Enum
{public static final Color RED = new Color();//枚举中的常量,可以看作是一个个对象,看到这儿应该get到枚举中定义属性的操作了public static final Color BLUE = new Color();public static final Color GREEN = new Color();
}

看到上面的反编译代码,对枚举中定义成员变量,枚举值有属性值的操作应该捋顺了!举个定义属性的简单例子:

public enum Domain {XB("11","西北"),HD("13","华东"),DB("14","东北"),HB("15","华北");private String code;private String name;Domain(String code,String name) {this.code = code;this.name = name;}public String getCode() {return code;}public String getName(){return name;}
}

3、自定义属性枚举类和常量的对比

上面提到所有的枚举值都是 public static final 的,可能会有疑问:那直接用常量不得了?

===>

自定义属性枚举是常量的升级版,二者有各自的应用场景。当就只需要一个静态变量名 = 值 时,直接用常量自然最快,如:

在这里插入图片描述

但当你的一个值背后需要连着多个信息时,就只能用枚举+自定义属性来表达!

4、常用方法

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。

枚举类中常用的三个方法:values()、ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

  • values() 返回枚举类中所有的值
  • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样
  • valueOf()方法返回指定字符串值的枚举常量
enum Color
{RED, GREEN, BLUE;
}public class Test
{public static void main(String[] args){// 调用 values()Color[] arr = Color.values();// 迭代枚举for (Color col : arr){// 查看索引System.out.println(col + " at index " + col.ordinal());}// 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentExceptionSystem.out.println(Color.valueOf("RED"));// System.out.println(Color.valueOf("WHITE"));}
}

运行结果:

RED at index 0
GREEN at index 1
BLUE at index 2
RED

5、枚举自定义属性在开发中的应用:字典表

看一个例子,有一个审核流的需求,审核状态只有四种,定义字典表:

在这里插入图片描述

为了后面写代码方便和规范,定义下面这个枚举类

import brave.internal.Nullable;import java.util.HashMap;
import java.util.Map;public enum AuditStatusEnum {BEFORE("before","待提交"),WAIT("wait", "待审核"),NO("no", "审核未通过"),PASS("pass","审核通过");String code;String name;AuditStatusEnum(String code, String name) {this.code = code;this.name = name;}private static final Map<String, AuditStatusEnum> mappings = new HashMap<>(5);static {for (AuditStatusEnum statusEnum : values()) {mappings.put(statusEnum.code, statusEnum);}}public String getCode(){return code;}public String getName(){return name;}@Nullablepublic static AuditStatusEnum resolve(@Nullable String code) {return (code != null ? mappings.get(code) : null);}
}

分析:

  • 两个属性,一个为code,一个为中文名,常见操作
  • values()方法获取枚举成员的所有值,返回一个数组
  • 写静态代码块,遍历上面的数组,以枚举值的code为键,以枚举值本身为值,放进Map集合
  • 静态方法resolve()则是根据枚举值的code查询枚举值
  • 定义静态方法resolve,妙在利用了Java类加载的时机之一 : 访问静态方法 。访问静态方法 ==> 类加载 ==> 静态代码块执行 ⇒ 枚举值被全存到Map中,方便后面查询
/定义了上面的字典对应的枚举类后,写业务逻辑代码:if (xxDto.getAuditCode().equals(AuditStatusEnum.NO.getCode())){return new MyException("审核未通过,不可操作!");
}


在这里插入图片描述

6、补充:入参校验

最后,工作时看到同事写的这个入参校验也蛮有意思,记录一下:


有个需求,它的某个接口有个传参,如排序字段orderField,该字段的可取值固定,只有create_time和name,为了防止非法传参,需要对这个入参做校验,此时也可用自定义属性的枚举类实现。

//当然想实现这个校验,直接把字段塞进集合,判断传参的值在不在集合中也能实现
//但这样一来后期扩展不方便,二来则是每个公司的代码规范要求

接下来演示枚举类:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;@Getter
@AllArgsConstructor
public enum OrderFieldEnum {CREATE_TIME("createTime", "create_time"),NAME("name","name");private final String value;  //值private final String field;  //对应数据库中的字段,方便后面写业务和Mapper层代码private static final Map<String, OrderFieldEnum> map = new HashMap<>();@JsonCreatorpublic static OrderFieldEnum check(String value) {//这里的判断map为空则遍历枚举类的值放进Map中//这个操作和上面的利用类加载时机初始化Map集合一个目的if (map.isEmpty()) {for (OrderFieldEnum orderFieldEnum : OrderFieldEnum.values()) {map.put(orderFieldEnum.getValue(), orderFieldEnum);}}//如果在Map中找不到对应的key和传入的字段相等,则认为非法传参,即不支持这个排序字段if (!map.containsKey(value)) {throw new MyExceptionHandler("不支持这个排序字段");  //自定义异常,在全局异常处理器处理}//否则返回整个枚举对象return map.get(value);}@JsonValuepublic String getValue() {return value;}
}

此时,校验入参可:

OrderFieldEnum.check(dto.getOrderField().getValue());

记录下他的另一种校验的实现方式,虽然写多了,但通用性更强

checkParamRegion(dto.getOrderField(), List.of(OrderFieldEnum.CREATE_TIME, OrderFieldEnum.NAME));public void checkParamRegion(Object param, Collection<?> regions) {//判断Object param是集合类型还是非集合if (param instanceof List) {List list = (List) param;for (Object o : list) {if (!regions.contains(o)) {throw new MyExceptionHandler("参数超过了给定范围");}}} else {if (!regions.contains(param)) {throw new MyExceptionHandler("参数超过了给定范围");}}}

最后,写mapper层的排序,拿排序字段可:

OrderFieldEnum.CREATE_TIME.getField()

http://chatgpt.dhexx.cn/article/wRFlwggJ.shtml

相关文章

Java 枚举(Enum)使用

文章目录 枚举引入enum关键字实现枚举enum关键字实现枚举注意事项enum常用方法一览表enum课堂练习enum实现接口 枚举引入 创建Season类, 实例化春夏秋冬四个实例 Season对象有如下特点 1.季节的值是有限的几个值(spring, summer, autumn, winter) 2.只读&#xff0c;不需要修…

Java枚举详解

目录 Java枚举详解 基本介绍 1.自定义类实现枚举 2.使用enum关键字实现枚举 使用enum关键字实现枚举的注意事项 enum的常用方法 enum的使用细节 Java枚举详解 基本介绍 枚举对应英文(enumeration,简写 enum) 枚举是一组常量的集合 枚举属于一种特殊的类&#xff0c;里…

Java枚举(enum)

枚举是一个被命名的整型常数的集合&#xff0c;用于声明一组带标识符的常数。枚举在曰常生活中很常见&#xff0c;例如一个人的性别只能是“男”或者“女”&#xff0c;一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时&#xff0c;就可以将它定义为…

如何使用pFuzz以多种方法验证Web应用程序防火墙的安全性

关于pFuzz pFuzz是一款功能强大的Web应用程序防火墙安全检测/绕过工具&#xff0c;可以帮助广大研究人员同时通过多种方式绕过目标Web应用程序防火墙&#xff0c;以测试WAF的安全性。 pFuzz本质上是一款高级红队模糊测试工具&#xff0c;主要用于研究目的。pFuzz基于Python编…

jieba java_【NLP】【一】中文分词之jieba

声明&#xff1a;本文参考jieba官方文档而成&#xff0c;官方链接&#xff1a;https://github.com/fxsjy/jieba 【一】jieba安装 pip install jieba 【二】jieba简介 简介可见jieba官方说明&#xff1a;https://pypi.org/project/jieba/ 总而言之&#xff0c;jieba用于中文分词…

jieba 分词

一.介绍&#xff1a; jieba: “结巴”中文分词&#xff1a;做最好的 Python 中文分词组件 “Jieba” (Chinese for “to stutter”) Chinese text segmentation: built to be the best Python Chinese word segmentation module. 完整文档见 : GitHub: https://github.com…

jieba学习

Jieba jieba的安装主要功能1.主要有三种模式&#xff1a;2. 加载词典3.词性标注4.关键词提取5.Tokenize&#xff1a;返回词语在原文的起止位置 jieba的安装 先在 [http://pypi.python.org/pypi/jieba/]下载 &#xff0c;解压后运行 python setup.py install 或者pin install j…

jieba 结巴分词详解

&#x1f517; 运行环境&#xff1a;python3&#x1f6a9; 作者&#xff1a;K同学啊&#x1f947; 精选专栏&#xff1a;《深度学习100例》&#x1f525; 推荐专栏&#xff1a;《新手入门深度学习》&#x1f4da; 极品专栏&#xff1a;《Matplotlib教程》&#x1f4d4; 选自专栏…

NLP基本工具之jieba详解

jieba的作用只有分词吗&#xff1f; 简介 jieba&#xff08;结巴&#xff09;是百度工程师Sun Junyi开发的一个开源库&#xff0c;在GitHub上很受欢迎&#xff0c;使用频率也很高。 GitHub链接&#xff1a;https://github.com/fxsjy/jieba jieba最流行的应用是分词&#xff0…

jieba分词的最详细解读

目录 一&#xff0c;什么是jieba&#xff08;结巴&#xff09;库&#xff1f; 二&#xff0c;jieba库的使用规则 三&#xff0c;jieba库具体使用和实例 一&#xff0c;什么是jieba&#xff08;结巴&#xff09;库&#xff1f; 字如其名&#xff0c;结巴库主要用于中文分词&…

python中jieba库使用教程

jieba是python的一个中文分词库&#xff0c;下面介绍它的使用方法。 安装 方式1&#xff1a; pip install jieba方式2&#xff1a; 先下载 http://pypi.python.org/pypi/jieba/ 然后解压&#xff0c;运行 python setup.py install 功能 下面介绍下jieba的主要功能&#xff…

基于python中jieba包的详细使用介绍

一&#xff0c;jieba的介绍 jieba 是目前表现较为不错的 Python 中文分词组件&#xff0c;它主要有以下特性&#xff1a; 支持四种分词模式&#xff1a; 精确模式全模式搜索引擎模式paddle模式 支持繁体分词 支持自定义词典 MIT 授权协议 二&#xff0c;安装和使用 1&am…

CRC校验码的计算

循环冗余检验的原理&#xff1a; 在发送端&#xff0c;先把数据划分为组&#xff0c;假定每组k个比特&#xff0c;假定一个待传送的数据M&#xff08;k位&#xff09;&#xff0c;CRC运算就是在数据M的后面添加供差错检测用的n位冗余码&#xff0c;然后构成一个帧发送出去&…

CRC校验简单记录

先聊聊奇偶校验 所谓通讯过程的校验是指在通讯数据后加上一些附加信息&#xff0c;通过这些附加信息来判断接收到的数据是否和发送出的数据相同。校验得通信双方都有才行&#xff0c;接收方收到数据后进行计算得到一个校验值&#xff0c;与发送方发的校验值比较&#xff0c;如果…

CRC校验总结

事实上网上很多CRC校验算法&#xff0c;在接收端进行CRC校验时&#xff0c;余数不为零。这往往是因为CRC校验算法本身是有问题的&#xff0c;但不妨碍我们进行校验。接收端可以对需要校验的字段带入CRC校验算法&#xff0c;计算得到校验值&#xff0c;并与发送数据中的校验值进…

CRC校验码计算,以常用CRC-8为例

CRC即循环冗余校验码&#xff1a;是数据通信领域中最常用的一种查错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。 CRC校验原理&#xff1a;在要发送的帧后面附加一个数&#xff0c;生成一个新帧发送给接收端。它要使所生成的新帧能与发送端和接收端共同…

CRC校验码举例

CRC校验码举例 一、首先复习一下异或运算&#xff08;XOR&#xff09;,相同得0&#xff0c;相异得1. 二、多项式算数 使用多项式算数是为了是为了在进行二进制计算时无需考虑进位问题。 CRC中用到的除数正是由多项式的各项系数组成。 比如1&#xff0c;CRC除数为10111。 三、…

CRC校验查表法原理及实现(CRC-16)

绪论 在网上浏览了很多关于CRC校验的文章&#xff0c;基本上都是针对CRC校验原理的阐述以及关于CRC校验查表法的实际应用以及具体软件实现方法。 至于查的表是怎么来的&#xff0c;软件为什么要这样实现很多文章并没有说明。本篇文章就针对这两点问题进行总结和归纳&#xff0…

CRC校验原理

线性分组码中有一种重要的码称为循环码&#xff08;Cyclic code&#xff09;&#xff0c;这种码编码和解码都不太复杂&#xff0c;而且检&#xff08;纠&#xff09;错能力较强。循环码除了具有线性分组码的一般性质外&#xff0c;还具有循环性。循环性是指任一码组循环一位以后…

CRC码计算及校验原理计算

如何根据多项式计算 循环CRC码 5.3.2 循环冗余校验检错方案 奇偶校验码&#xff08;PCC&#xff09;只能校验一位错误&#xff0c;本节所要介绍的循环冗余校验码&#xff08;CRC&#xff09;的检错能力更强&#xff0c;可以检出多位错误。 1. CRC校验原理 CRC校验原理看…