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

Java 枚举(enum)剖析

目录

Java 枚举(enum)概述

枚举常量 & values 遍历

枚举属性、方法、参数

枚举实现接口

枚举定义抽象方法、静态方法

同一工具类中维护多个枚举

switch case 枚举

枚举创建单例


Java 枚举(enum)概述

1、Java JDK 1.5 新增的 enum 关键词,可以定义枚举类,如 public enum WeekEnum { }.

2、使用 enum 定义后的枚举类在编译后默认继承 java.lang.Enum 类,而不是普通的继承 Object 类。由于 Java 不支持多继承,所以枚举不能再显示的继承其他类,但是可以实现接口。

3、Enum 类默认实现了 Java.lang.Comparable 接口与 Serializable 接口。

4、enum 声明后,该类会被编译器加上 final 声明(如同 String),故枚举无法被继承。

5、枚举类内部定义的枚举值就是该类的实例,且必须在第一行定义,当类初始化时,这些枚举值会被实例化,互相以逗号分隔。 如 "Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday"。

6、枚举规定好了指定的取值范围,所有的内容只能从指定的范围中取得。

7、枚举是一种类型,用于定义变量,以限制变量的赋值;通过 "枚举名.值" 取得枚举值,每个值都是一个 Enum 实例。

8、枚举是一个特殊的类,可以定义自己的 field(包括静态属性)、方法(包括静态方法)、可以实现接口,也可以定义自己的构造器。

9、枚举类的构造方法默认用 private 修饰的,且不能出现 public 构造方法,因此无法 new 一个枚举对象。

10、实际编程中往往存在着这样的 "数据集",它们的数值是稳定的、元素个数是有限的,例如星期一到星期日,春夏秋冬四季等等,很多时候大家选择使用常量。 JDK 1.5 开始有了枚举,其实可以把相关的常量放到一个枚举类型里,枚举提供了比常量更多的方法,使用起来更加方便。

枚举的构造器私有,每一个枚举值都是一个枚举实例,编译后自动产生。

枚举值的参数与构造器的参数相对应:

  枚举值后面没跟参数时,对应构造器的无参构造,
  枚举值后面有跟参数时,必须要有参数个数且类型相同的构造器与之对应,以及设置相应的成员变量。

枚举编译构建实例顺序:枚举值后面的实参值->找到对应的构造方法->注入给相应的成员变量。因为构造器可以重载,所以枚举值后面的参数可以不同,包括类型与个数。
每个枚举值既可以调用自己独有的属性,即后面的参数值,也可以调用公共的属性,即可调用自己下面独有的方法,也可调用公共的方法。
当枚举值/枚举常量没有带参数时,则没必要构造器,反之如果枚举值有参数,则必须有构造器与之对应。
枚举常用API方法
方法描述
toStringEnum 类重写了 toString 方法,返回枚举常量名。
values 每个枚举类都有一个 values 方法,该方法可以遍历枚举类的所有实例.
static Enum valueOf(Class enumClass, String name)返回指定名字、给定类的枚举常量
boolean equals(Object other)比较枚举是否相等。也可以直接使用 == 比较是否相等。

枚举常量 & values 遍历

1、定义枚举。

public enum WeekEnum1 {/*** 最简单的枚举形式,使用逗号分隔,结尾分号此时可以省略* 每一个值都代表当前的枚举实例,通过 枚举名.值 获取*/Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
    /*** 每个枚举类都有一个 values 方法,该方法可以遍历枚举类的所有实例.* 1、可以直接通过类名调用 values 方法,小哥哥都是一样的。* 2、也可以通过枚举常量调用 values 方法,小哥哥都是一样的。*/@Testpublic void testValues() {WeekEnum1[] values = WeekEnum1.values();for (WeekEnum1 weekEnum1 : values) {// Monday	Tuesday	Wednesday	Thursday	Friday	Saturday	SundaySystem.out.print(weekEnum1 + "\t");}System.out.println();WeekEnum1[] values1 = WeekEnum1.Sunday.values();for (WeekEnum1 weekEnum1 : values1) {// Monday	Tuesday	Wednesday	Thursday	Friday	Saturday	SundaySystem.out.print(weekEnum1 + "\t");}}

src/main/java/org/example/enums/WeekEnum1.java · 汪少棠/java-se - Gitee.com

测试枚举:src/main/java/org/example/enums/WeekEnumTest1.java · 汪少棠/java-se - Gitee.com

枚举属性、方法、参数

1、枚举像普通的类一样可以添加属性和方法(包括静态或非静态的属性或方法)。注意枚举值要写在最前面,且以分号结尾,否则编译出错。

2、枚举常量后面可以接括号定义枚举参数,这些参数会通过对应的构造器自动给属性赋值。"枚举参数 -> 对应的构造器 -> 属性" 完成赋值。

public enum WeekEnum2 {/*** 枚举值写在最前面,有其他内容时,必须以分号结尾。* 因为枚举只能通过常量获取枚举实例,所以枚举参数必须与构造器中的参数对应* 匹配两个参数的构造器创建 1-6 实例* 匹配三个参数的构造器创建 Sunday 实例*/Monday(1, "星期一"),Tuesday(2, "星期二"),Wednesday(3, "星期三"),Thursday(4, "星期四"),Friday(5, "星期五"),Saturday(6, "星期六"),Sunday(7, "星期天", "周末");/*** 属性名称可以随便取,只需要构造器中的参数类型必须与上面的枚举参数类型对应*/private final Integer code;private final String name;private String ext;/*** 支持定义静态属性*/public static String summary;/*** 构造器默认是 private ,外部无法 new 枚举对象,只能通过上面的常量获取实例,必须与枚举参数对应** @param code* @param name*/WeekEnum2(Integer code, String name) {this.code = code;this.name = name;}WeekEnum2(Integer code, String name, String ext) {this.code = code;this.name = name;this.ext = ext;}/*** 因为枚举常量的参数都是通过内部私有的构造器赋值的,无法通过外部赋值,所以没必要提供 setter方法* 但是可以提供 getter 方法来获取枚举参数值** @return*/public Integer getCode() {return code;}public String getName() {return name;}public String getExt() {return ext;}/*** 获取工作日 周一到周五-----支持静态方法** @return*/public static Set<WeekEnum2> getWorkDays() {Set<WeekEnum2> workDays = new HashSet<>(5);workDays.add(WeekEnum2.Monday);workDays.add(WeekEnum2.Tuesday);workDays.add(WeekEnum2.Wednesday);workDays.add(WeekEnum2.Thursday);workDays.add(WeekEnum2.Friday);return workDays;}/*** 根据 星期数字获取对应的星期中文** @param code 星期几 [1,7]* @return :返回中文,星期一、星期二、...*/public static WeekEnum2 getWorkDayByCode(Integer code) {WeekEnum2[] values = WeekEnum2.values();for (WeekEnum2 value : values) {if (StrUtil.equals(String.valueOf(value.code), String.valueOf(code))) {return value;}}return null;}
}

src/main/java/org/example/enums/WeekEnum2.java · 汪少棠/java-se - Gitee.com

src/main/java/org/example/enums/WeekEnum2Test.java · 汪少棠/java-se - Gitee.com

枚举实现接口

1、先准备一个接口:

import java.util.Map;
public interface WeekEnumInterface {Integer getCode();String getName();Map<String, Object> getDataMap();
}

src/main/java/org/example/enums/WeekEnum3Interface.java · 汪少棠/java-se - Gitee.com

2、定义枚举并实现接口

public enum WeekEnum3 implements WeekEnum3Interface {//枚举值写在最前面,有其他内容时,必须以分号结尾。//因为枚举只能通过常量获取枚举实例,所以枚举参数必须与构造器中的参数对应//匹配两个参数的构造器创建实例Monday(1, "星期一"),Tuesday(2, "星期二"),Wednesday(3, "星期三"),Thursday(4, "星期四"),Friday(5, "星期五"),Saturday(6, "星期六"),Sunday(7, "星期天");/*** 属性名称可以随便取,但是构造器中的参数类型必须与上面的枚举参数类型对应*/private final Integer code;private final String name;/*** 构造器默认是 private ,外部无法 new 枚举对象,只能通过上面的常量获取实例,必须与枚举参数对应** @param code* @param name*/WeekEnum3(Integer code, String name) {this.code = code;this.name = name;}@Overridepublic Integer getCode() {return this.code;}@Overridepublic String getName() {return this.name;}/*** 将整个枚举参数转为 Map 结构** @return*/@Overridepublic Map<String, Object> getDataMap() {Map<String, Object> dataMap = new HashMap<>(WeekEnum3.values().length);for (WeekEnum3 weekEnum : WeekEnum3.values()) {dataMap.put(weekEnum.code + "", weekEnum.name);}return dataMap;}
}

src/main/java/org/example/enums/WeekEnum3.java · 汪少棠/java-se - Gitee.com

测试代码:

src/main/java/org/example/enums/WeekEnum3Test.java · 汪少棠/java-se - Gitee.com

枚举定义抽象方法、静态方法

1、枚举中可以有抽象方法,且由枚举值/枚举常量提供方法实现。枚举类如下:

public enum WeekEnum4 {/*** 枚举值写在最前面,有其他内容时,必须以分号结尾。* 因为枚举只能通过常量获取枚举实例,所以枚举参数必须与构造器中的参数对应*/Monday(1, "星期一") {@Overridepublic String toSplitString() {return Monday.code + "," + Monday.name;}},Tuesday(2, "星期二") {@Overridepublic String toSplitString() {return Tuesday.getCode() + "," + Tuesday.getName();}};/*** 属性名称可以随便取,但是构造器中的参数类型必须与上面的枚举参数类型对应*/private final Integer code;private final String name;/*** 全部枚举值放入到常量中* 在静态代码块中为其赋值*/private static final Map<Integer, WeekEnum4> weekEnum4Map = new HashMap<>();static {for (WeekEnum4 weekEnum4 : values()) {weekEnum4Map.put(weekEnum4.getCode(), weekEnum4);}}/*** 构造器默认是 private ,外部无法 new 枚举对象,只能通过上面的常量获取实例,必须与枚举参数对应** @param code* @param name*/WeekEnum4(Integer code, String name) {this.code = code;this.name = name;}public Integer getCode() {return code;}public String getName() {return name;}/*** 方法要是 public 修饰外部才能调用** @return*/public abstract String toSplitString();/*** 根据数字获取星期枚举* 静态方法,方便通过类名调用。** @param index* @return*/public static WeekEnum4 of(Integer index) {return weekEnum4Map.get(index);}/*** 获取全部枚举项** @return*/public static List<WeekEnum4> list() {WeekEnum4[] values1 = WeekEnum4.values();ArrayList<WeekEnum4> weekEnum4s = Lists.newArrayList(values1);return weekEnum4s;}
}

测试代码:src/main/java/org/example/enums/WeekEnum4Test.java · 汪少棠/java-se - Gitee.com

同一工具类中维护多个枚举

public class EnumComm {/*** 红绿灯颜色枚举*/public enum ColorEnum {Red("red", "红色"),Yellow("yellow", "黄色"),Green("green", "绿色");private final String code;private final String name;ColorEnum(String code, String name) {this.code = code;this.name = name;}public String getCode() {return code;}public String getName() {return name;}}/*** 系统上线省份枚举*/public enum AreaEnum {HuNan("43", "湖南"),HeNan("41", "河南"),LiaoNiang("21", "辽宁");private final String code;private final String name;AreaEnum(String code, String name) {this.code = code;this.name = name;}public String getCode() {return code;}public String getName() {return name;}}
}

src/main/java/org/example/enums/EnumComm.java · 汪少棠/java-se - Gitee.com

src/main/java/org/example/enums/EnumCommTest.java · 汪少棠/java-se - Gitee.com

src/main/java/org/example/enums/EscalationConsts.java · 汪少棠/java-se - Gitee.com

switch case 枚举

    /*** 枚举作为 switch (xxx) 参数时,case 中的值必须是枚举常量的非限定名称。* 不能是 枚举.常量 的方式,否则编译不通过:* An enum switch case label must be the unqualified name of an enumeration constant.*/@Testpublic void testSwitchCase() {WeekEnum2 workDayByCode = WeekEnum2.getWorkDayByCode(9);switch (workDayByCode) {// 这种方式是编译不通过的,必须是非限定名称// case WeekEnum2.Monday:case Monday:System.out.println(workDayByCode.getCode());break;case Saturday:System.out.println(workDayByCode.getName());break;case Sunday:System.out.println(workDayByCode.getExt());break;default:System.out.println(workDayByCode);break;}}

src/main/java/org/example/enums/WeekEnum2Test.java · 汪少棠/java-se - Gitee.com

枚举创建单例

/*** 枚举创建单例** @author wangMaoXiong* @version 1.0* @date 2022/12/16 14:30*/
public class Person {private String agencyCode;private String idenNo;private String idenType;private String perName;private String sexCode;private String control;/*** 私有化构造函数*/private Person() {}private enum SingletonEnum {/*** 枚举类内部定义的枚举值就是该类的实例,必须在第一行定义,当类初始化时,这些枚举值会被实例化.* 创建一个枚举对象,该对象天生为单例。* 枚举INSTANCE会在类加载初始化的时候创建,而Java类的加载和初始化过程都是线程安全的。*/INSTANCE;/*** 枚举是一个特殊的类,可以定义自己的 field(包括静态属性)、方法(包括静态方法)、可以实现接口,也可以定义自己的构造器。*/private final Person person;/*** 枚举类的构造方法默认用 private 修饰的,且不能出现 public 构造方法,因此无法 new 一个枚举对象。*/SingletonEnum() {person = new Person();}public Person getInstance() {return person;}}/*** 对外暴露一个获取单例对象的静态方法** @return*/public static Person getInstance() {return SingletonEnum.INSTANCE.getInstance();}// 省略 getter、setter、toString 方法
}

src/main/java/org/example/enums/Person.java · 汪少棠/java-se - Gitee.com。

src/main/java/org/example/enums/PersonTest.java · 汪少棠/java-se - Gitee.com。

http://www.xdnf.cn/news/807877.html

相关文章:

  • AI编程助手 Kodezi : 记录、分享一个 VS code 插件
  • 如何符合E-NCAP测试规范?TPT让AEB场景测试更简单:AEB系统的测试场景 | 测试执行与评估 | 测试用例渲染展示
  • 允许Traceroute探测
  • SQL中的distinct的使用方法
  • System.getProperty()方法获取系统变量
  • ubuntu 10.04 下载源列表
  • 《疯狂的站长》读后感1
  • 惊奇的发现37个上班族必看的网站,不看就OUT了
  • iPhone4s降级ios6.1.3流程总结
  • 分享几个普通人做私活赚外快的好地方
  • 大一python编程题库和答案,大一python程序设计考题
  • 值得收藏 Modbus RTU 协议详解
  • 火车头发布html模板,织梦V5.7火车头采集器全套Web发布模块(含软件模型、图集模型、商品模型)...
  • opendirve ,好用的免费直链(外链)网盘
  • 「营业日志 2020.11.26」一道纳什均衡数数题
  • Sky入围CCTV06体坛风云人物侯选名单
  • 素材类dedecms织梦模板免费下载
  • Visual Studio 6.0 企业版 下载
  • DOS操作系统
  • 一文搞定:whois数据库查询域名信息(WHOIS)
  • MSN登陆不了怎么办
  • iPad2 4.3.3完美越狱教程 一键即可操作
  • 在Android中使用SyncAdapter同步数据全攻略
  • HTB靶场 Perfection
  • U盘修复技巧大全
  • 支付宝的架构
  • QQ分享 QQ空间分享 API链接:
  • 黑客帝国之酷炫屏保数字雨
  • 十款性能最佳的压缩算法
  • Nero注册与下载