1.前言
enum
的全称为 enumeration, 是 JDK 1.5 中引入的新特性。
在Java中,被 enum
关键字修饰的类型就是枚举类型。本文以状态为例 形式如下:
@Getter
public enum IPSFStatusEnum {
INIT("待处理"),
PROCESSING("处理中"),
CANCELED("已取消"),
SUCCESS("处理成功"),
FAIL("处理失败");
}
如果枚举不添加任何方法,枚举值默认为从0开始的有序数值。以 状态枚举类型举例,它的枚举常量依次为 INIT:0,PROCESSING:1,CANCELED:2.....
枚举的好处:可以将常量组织起来,统一进行管理。
枚举的典型应用场景:错误码、状态机等一些固定值。
尽管 enum
看起来像是一种新的数据类型,事实上,enum是一种受限制的类,并且具有自己的方法。
创建enum时,编译器会为你生成一个相关的类,这个类继承自 java.lang.Enum
。
java.lang.Enum
类声明
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable { ... }
所以枚举类不能继承
2.枚举的方法
在enum中,提供了一些基本方法:
values()
:返回 enum 实例的数组,而且该数组中的元素严格保持在 enum 中声明时的顺序。
name()
:返回实例名。
ordinal()
:返回实例声明时的次序,从0开始。
getDeclaringClass()
:返回实例所属的 enum 类型。
equals()
:判断是否为同一个对象。
可以使用 ==
来比较enum
实例。
此外,java.lang.Enum
实现了Comparable
和 Serializable
接口,所以也提供 compareTo()
方法。
枚举可以添加普通方法、静态方法、抽象方法、构造方法 Java 虽然不能直接为实例赋值,但是它有更优秀的解决方案:为 enum 添加方法来间接实现显示赋值。 创建 enum 时,可以为其添加多种方法,甚至可以为其添加构造方法。
↓↓↓↓↓↓↓↓
/**
* 描 述:订单状态
* 创 建 者:wby
* 创建时间:2024/8/11 10:41
*/
@Getter
public enum IPSFStatusEnum {
INIT("待处理"),
PROCESSING("处理中"),
CANCELED("已取消"),
SUCCESS("处理成功"),
FAIL("处理失败");
private final String description;
public String getCode() {
return this.name();
}
public static IPSFStatusEnum getBeanByName(String name) {
if (name != null && !name.equals("")) {
try {
return valueOf(name);
} catch (IllegalArgumentException var2) {
return null;
}
} else {
return null;
}
}
public static IPSFStatusEnum getBeanByCode(String code) {
if (Objects.isNull(code)) {
return null;
} else {
IPSFStatusEnum[] vals = values();
IPSFStatusEnum[] var2 = vals;
int var3 = vals.length;
for (int var4 = 0; var4 < var3; ++var4) {
IPSFStatusEnum val = var2[var4];
if (val.getCode().equals(code)) {
return val;
}
}
return null;
}
}
public static String getDescriptionByCode(String code) {
if (Objects.isNull(code)) {
return null;
} else {
IPSFStatusEnum anEnum = getBeanByCode(code);
return anEnum != null ? anEnum.description : null;
}
}
public String getDescription() {
return this.description;
}
private IPSFStatusEnum(final String description) {
this.description = description;
}
测试↓↓↓↓↓↓↓↓
import com.jiyun.enums.IPSFStatusEnum;
/**
* 描 述:枚举测试
* 创 建 者:wby
* 创建时间:2024/8/11 10:51
*/
public class EnumTest {
public static void main(String[] args) {
System.out.println("code description 输出=========================");
System.out.println("code: ".concat(IPSFStatusEnum.INIT.getCode()).concat(" description: ").concat(IPSFStatusEnum.INIT.getDescription()));
System.out.println("code: ".concat(IPSFStatusEnum.PROCESSING.getCode()).concat(" description: ").concat(IPSFStatusEnum.PROCESSING.getDescription()));
System.out.println("code: ".concat(IPSFStatusEnum.CANCELED.getCode()).concat(" description: ").concat(IPSFStatusEnum.CANCELED.getDescription()));
System.out.println("code: ".concat(IPSFStatusEnum.SUCCESS.getCode()).concat(" description: ").concat(IPSFStatusEnum.SUCCESS.getDescription()));
System.out.println("code: ".concat(IPSFStatusEnum.FAIL.getCode()).concat(" description: ").concat(IPSFStatusEnum.FAIL.getDescription()));
System.out.println("code description 结束=========================");
System.out.println("根据code获取枚举 开始=========================");
System.out.println("String code = INIT" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode("INIT"))));
System.out.println("String code = PROCESSING" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode("PROCESSING"))));
System.out.println("String code = CANCELED" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode("CANCELED"))));
System.out.println("String code = SUCCESS" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode("SUCCESS"))));
System.out.println("String code = FAIL" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode("FAIL"))));
System.out.println("String code = ''" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getBeanByCode(""))));
System.out.println("根据code获取枚举 结束=========================");
System.out.println("根据code获取description 开始=========================");
System.out.println("String code = INIT" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode("INIT"))));
System.out.println("String code = PROCESSING" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode("PROCESSING"))));
System.out.println("String code = CANCELED" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode("CANCELED"))));
System.out.println("String code = SUCCESS" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode("SUCCESS"))));
System.out.println("String code = FAIL" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode("FAIL"))));
System.out.println("String code = ''" + " 获取枚举: ".concat(String.valueOf(IPSFStatusEnum.getDescriptionByCode(""))));
System.out.println("根据code获取description 结束=========================");
}
}
输出↓↓↓↓↓↓↓↓
code description 输出=========================
code: INIT description: 待处理
code: PROCESSING description: 处理中
code: CANCELED description: 已取消
code: SUCCESS description: 处理成功
code: FAIL description: 处理失败
code description 结束=========================
根据code获取枚举 开始=========================
String code = INIT 获取枚举: INIT
String code = PROCESSING 获取枚举: PROCESSING
String code = CANCELED 获取枚举: CANCELED
String code = SUCCESS 获取枚举: SUCCESS
String code = FAIL 获取枚举: FAIL
String code = '' 获取枚举: null
根据code获取枚举 结束=========================
根据code获取description 开始=========================
String code = INIT 获取枚举: 待处理
String code = PROCESSING 获取枚举: 处理中
String code = CANCELED 获取枚举: 已取消
String code = SUCCESS 获取枚举: 处理成功
String code = FAIL 获取枚举: 处理失败
String code = '' 获取枚举: null
根据code获取description 结束=========================
3.枚举的特性
枚举的特性,归结起来就是一句话:
除了不能继承,基本上可以将 enum 看做一个常规的类。
我们经常使用switch语句来写状态机。JDK7以后,switch已经支持 int
、char
、String
、enum
类型的参数。这几种类型的参数比较起来,使用枚举的switch代码更具有可读性。
private static void test() {
IPSFStatusEnum ipsfStatusEnum = IPSFStatusEnum.INIT;
switch (ipsfStatusEnum) {
case INIT:
System.out.println("INIT");
break;
case PROCESSING:
System.out.println("PROCESSING");
break;
case CANCELED:
System.out.println("CANCELED");
break;
case SUCCESS:
System.out.println("SUCCESS");
break;
case FAIL:
System.out.println("FAIL");
break;
}
可以将类型相近的枚举通过接口或类组织起来。
但是一般用接口方式进行组织。
原因是:Java接口在编译时会自动为enum类型加上public static
修饰符;Java类在编译时会自动为 enum
类型加上static修饰符。看出差异了吗?没错,就是说,在类中组织 enum
,如果你不给它修饰为 public
,那么只能在本包中进行访问。
public class Pay{
public enum TransTypeEnum implements IPSFStatusEnum {...} // 省略代码
}
4.EnumSet和EnumMap
Java 中提供了两个方便操作enum的工具类——EnumSet 和 EnumMap。
EnumSet
是枚举类型的高性能 Set
实现。它要求放入它的枚举常量必须属于同一枚举类型。EnumMap
是专门为枚举类型量身定做的 Map
实现。虽然使用其它的 Map 实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用 EnumMap 会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值。这使得 EnumMap 的效率非常高。
private static void test2() {
// EnumSet的使用
System.out.println("EnumSet展示");
EnumSet<IPSFStatusEnum> errSet = EnumSet.allOf(IPSFStatusEnum.class);
for (IPSFStatusEnum e : errSet) {
System.out.println(e.name() + " : " + e.ordinal());
}
// EnumMap的使用
System.out.println("EnumMap展示");
EnumMap<IPSFStatusEnum, String> errMap = new EnumMap(IPSFStatusEnum.class);
errMap.put(IPSFStatusEnum.INIT, "待处理");
errMap.put(IPSFStatusEnum.PROCESSING, "处理中");
errMap.put(IPSFStatusEnum.SUCCESS, "处理成功");
for (Iterator<Map.Entry<IPSFStatusEnum, String>> iter = errMap.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry<IPSFStatusEnum, String> entry = iter.next();
System.out.println(entry.getKey().name() + " : " + entry.getValue());
}
}
输出↓↓↓↓↓↓↓↓
EnumSet展示
INIT : 0
PROCESSING : 1
CANCELED : 2
SUCCESS : 3
FAIL : 4
EnumMap展示
INIT : 待处理
PROCESSING : 处理中
SUCCESS : 处理成功
完结!
如果对Enum有更好了解 欢迎大家评论!