亲宝软件园·资讯

展开

Java enum枚举在实际项目中的常用方法

铭言明语 人气:1
> 在项目实际开发过程中,经常会遇到对某些固定的值、字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目中使用的方法。 # 知识点 * **枚举类命名** 枚举类的命名通常需要Enum为后缀,枚举成员名称需要全大写,单词间用下划线隔开。 * **枚举类不允许使用 extends 关键字** 枚举类默认会继承java.lang.Enum,由于java是单继承,所以在定义枚举类时不允许再继承其他类,但可以实现多个接口 * **枚举的比较可以直接使用 ==** 枚举是不允许被new出来的,枚举类里的构造函数都限定为私有化,是不允许使用public定义构造函数的。枚举的赋值,如果是同一个元素,则会指向同一个地址,所以是可以直接使用==的,当然在Enum类中,重写了equals方法(如下图),所以也是可以用equals来判断。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200229173048738.png) * **枚举常用方法** |方法名| 用途 | |--|--| | name() | 返回枚举常量名 | | toString() | 返回枚举常量名 | | values() | 返回枚举成员数组 | | valueOf() | 通过枚举常量名返回枚举 | | ordinal() | 返回枚举常量在enum声明中的位置,位置是从0开始计数的 | * **枚举在switch中的使用** 枚举在switch中的使用,优势在于能控制case的范围(看以下实例),并且在idea中有相关提示 * **枚举在单例模式的使用** 首先使用枚举类实现单例模式,写法相当简单,看最后的实例;其次枚举是线程安全、单一实例(由于构造方法都是私有的,不能被new) # 实例 ## 1. 最简单的枚举 > 在项目中经常会遇到一些固定值的定义,以往都是用常量来定义,以下用实例说明,为啥枚举的方式优于常量的方式,以下就以季节的定义为例 ### 1.1 使用常量来实现 ```java /** * @Description: 季节常量定义 */ public class SeasonConst { /** * 春季 */ public static final String SPRING = "SPRING"; /** * 夏季 */ public static final String SUMMER = "SUMMER"; /** * 秋季 */ public static final String AUTUMN = "AUTUMN"; /** * 冬季 */ public static final String WINTER = "WINTER"; } ``` **以上实例虽然实现了功能,但有两点比较明显的缺点:** 1. 常量值容易写错(特别是复制黏贴,但是忘记改对应的值,导致系统出bug),idea不会给任何提示。 比如,某人粗心,在复制黏贴代码时变成(将春季、夏季都定义成春季了): ```java /** * 春季 */ public static final String SPRING = "SPRING"; /** * 夏季 */ public static final String SUMMER = "SPRING"; ``` 2. 如果我想知道一年总共多少个季节,咋整?用常量定义的类,有点捉襟见肘 ### 1.2 使用枚举来实现,可以实现常量的所有功能,并能轻松解决以上提出的常量的两个缺点 * 定义枚举类SeasonEnum ```java public enum SeasonEnum { /** * 春季 */ SPRING, /** * 夏季 */ SUMMER, /** * 秋季 */ AUTUMN, /** * 冬季 */ WINTER } ``` **在SeasonEnum枚举类中,如果定义两个 SPRING,编译器会直接报错,很好解决了常量的第一个缺点** * 该枚举类的使用(1、获取枚举值的名称;2、枚举判断的使用;3、枚举循环的使用。**通过枚举的循环,很好解决了常量的第二个缺点**;) ```java //获取枚举值的名称,与toString得到的结果一样 String spring = SeasonEnum.SPRING.name(); System.out.println(spring); //枚举判断的使用 SeasonEnum springEnum1 = SeasonEnum.SPRING; SeasonEnum springEnum2 = SeasonEnum.SPRING; SeasonEnum summerEnum3 = SeasonEnum.SUMMER; //由于springEnum1、springEnum2都指向SPRING,所以输出true System.out.println("springEnum1 == springEnum2:" + (springEnum1 == springEnum2)); //由于springEnum1指向SPRING、summerEnum3指向SUMMER,所以输出false System.out.println("springEnum1 == summerEnum3:" + (springEnum1 == summerEnum3)); //循环枚举,打印枚举类中的所有枚举成员 SeasonEnum[] seasonEnums = SeasonEnum.values(); for (SeasonEnum seasonEnum : seasonEnums) { System.out.println(seasonEnum.name()); } ``` * 枚举在switch中的使用,如果case后跟不存在SeasonEnum类中的枚举(比如 case OTHER),则编译器会报错 ```java String enumName = "SPRING"; SeasonEnum seasonEnum = SeasonEnum.valueOf(enumName); switch (seasonEnum){ case SPRING: System.out.println(seasonEnum.name()); break; case SUMMER: System.out.println(seasonEnum.name()); break; case AUTUMN: System.out.println(seasonEnum.name()); break; case WINTER: System.out.println(seasonEnum.name()); break; default: System.out.println("other"); } ``` ## 2.在枚举中使用自定义属性和方法 > 项目中经常也会遇到一些字典项的定义,比如性别,包含存入数据库中的值,以及显示在页面上的值。以下通过实例来实现性别字典。 * 定义SexEnum(注意看代码中的注解) ```java public enum SexEnum { MAN("man","男"), WOMEN("women","女"); private String sexCode; private String sexName; /** * 自定义构造函数,以完成枚举对sexCode、sexName赋值 * @param sexCode * @param sexName */ SexEnum(String sexCode,String sexName){ this.sexCode = sexCode; this.sexName = sexName; } /** * 获取sexCode * @return */ public String getSexCode() { return sexCode; } /** * 获取sexName * @return */ public String getSexName() { return sexName; } /** * 项目中经常会根据code,转换成对应的name * 所以这里自定义方法,根据sexCode获取sexName * 通过循环enum来实现 * @param sexCode * @return */ public static String getSexNameByCode(String sexCode){ String sexName = "sexCode不存在"; SexEnum[] sexEnums = SexEnum.values(); for (SexEnum sexEnum : sexEnums) { if(sexEnum.getSexCode().equals(sexCode)){ sexName = sexEnum.getSexName(); break; } } return sexName; } /** * 项目中也有根据name,转换成对应的code * 所以这里自定义方法,根据sexName获取sexCode * 通过循环enum来实现 * @param sexName * @return */ public static String getSexCodeByName(String sexName){ String sexCode = "sexName不存在"; SexEnum[] sexEnums = SexEnum.values(); for (SexEnum sexEnum : sexEnums) { if(sexEnum.getSexName().equals(sexName)){ sexCode = sexEnum.getSexCode(); break; } } return sexCode; } /** * 根据sexCode获取SexEnum,在switch中使用 * 通过循环enum来实现 * @param sexCode * @return */ public static SexEnum getEnumByCode(String sexCode){ SexEnum[] sexEnums = SexEnum.values(); for (SexEnum sexEnum : sexEnums) { if(sexEnum.getSexCode().equals(sexCode)){ return sexEnum; } } return null; } /** * 重写toString方法 * @return */ @Override public String toString() { return this.sexCode + ":" + this.sexName; } } ``` * SexEnum枚举类的使用 ```java public class EnumMain { public static void main(String[] args){ //循环带自定义方法的枚举 SexEnum[] sexEnums = SexEnum.values(); for (SexEnum sexEnum : sexEnums) { System.out.println("sexCode:"+sexEnum.getSexCode()); System.out.println("sexName:"+sexEnum.getSexName()); System.out.println("sexCode:sexName="+sexEnum.toString()); } //根据sexCode获取sexName String sexName = SexEnum.getSexNameByCode("women"); System.out.println("根据sexCode获取sexName:" + sexName); //根据sexName获取sexCode String sexCode = SexEnum.getSexCodeByName("男"); System.out.println("根据sexName获取sexCode:" + sexCode); //通过传入的sexCode使用switch testSexEnumSwitch("women"); } /** * 实际项目中,基本上都是传sexCode的,所以这里也根据传入的sexCode,使用switch方法 * @param sexCode */ private static void testSexEnumSwitch(String sexCode){ //自定义getEnumByCode方法,通过sexCode获取SexEnum SexEnum sexEnum = SexEnum.getEnumByCode(sexCode); switch (sexEnum){ case MAN: System.out.println(sexEnum.toString()); break; case WOMEN: System.out.println(sexEnum.toString()); break; default: System.out.println("other"); } } } ``` ## 3.通过枚举实现单例 * 单例定义 ```java public enum Singleton { INSTALL; /** * 自定义方法 */ public void yourMethod(){ System.out.println("do your business"); } } ``` * 调用方法 ```java Singleton.INSTALL.yourMethod(); ``` # 源码获取 以上示例都可以通过[我的GitHub](https://github.com/simonxie/javase-demo)获取完整的代码,[点击获取](https://github.com/simonxie/javase-demo/tree/master/src/main/java/com/simon/enumdemo)

加载全部内容

相关教程
猜你喜欢
用户评论