基本概念
枚举是JDK 1.5中引入的新特性。对应的关键字为enum。
其实枚举是一个特殊的类,这个类内部存储的是这个类的所有对象实例。
适用的场景
枚举一般适合用于有限个数的参数定义。例如已知个数的类型定义、各种状态的定义等。其实就是固定有限数量的全局变量。以支付业务作为例子,定义支付单的状态的时候,支付状态其实有固定的几个。这个时候就可以选择使用枚举了。
对应实例
介绍完适合的业务场景之后,我会基于场景的例子编写的一个实例。
/**
* 支付状态枚举,支付状态码(支付状态的中文名称)
* @author RJH
* @date 2018年1月6日
*/
public enum PayStatus {
N("待支付"),
P("支付中"),
S("支付成功"),
F("支付失败"),
C("取消支付");
/**
* 支付状态对应的中文名称
*/
private String statusName;
/**
* 枚举中只允许私有构造方法
* @param statusName
*/
private PayStatus(String statusName) {
this.statusName = statusName;
}
/**
* 获取支付状态对象对应的中文名称
* @return
*/
public String getStatusName() {
return statusName;
}
}
实例分析
- 枚举中每个成员实际上就是调用了构造方法之后产生的对象。实例中只是简单的做个示范,实际上可以更加复杂,例如加上状态数字码。
- 为什么构造方法为私有的?
这是枚举本身的定义所决定的,定义(引用自百度百科)如下:
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。
- 既然是有限集,那么构造方法就不会让其他类去调用。
这里要补充一点:一个枚举中允许有多个构造方法。
旧版本的解决方案
既然枚举是JDK 1.5中引入的新特性,那么在这个版本以前是怎么处理的呢?这时候一般都是选择使用接口来存储有限的支付状态,实例代码如下:
/**
* JDK 1.5以前的支付状态的处理方案
* @author RJH
* @date 2018年1月6日 下午6:58:12
*/
public interface PayStatus {
String N="待支付";
String P="支付中";
String S="支付成功";
String F="支付失败";
String C="取消支付";
}
枚举实例的优化
但是有时候我们会遇到需要判断一个支付状态是否是有效状态的情况(是否包含在枚举中),有人可能会选择使用枚举提供的valueOf()方法,但是这个方法如果遇到以下情况会抛出运行时异常:
//传入一个不存在的对象名
PayStatus.valueOf("A");
虽然可以使用try…catch去处理这种情况,但是可以使用以下方法处理:
/**
* 判断支付状态码是否有效
* @param status 支付状态码
* @return
*/
public static boolean isValid(String status){
//获取所有支付状态对象
PayStatus[] payStatusList=PayStatus.values();
boolean flag=false;
for (PayStatus payStatus : payStatusList) {
if(payStatus.name().equals(status)){//如果存在该状态码则为有效,中断循环
flag=true;
break;
}
}
return flag;
}
可以把上面的代码添加到支付状态的枚举类中,由枚举类来管理和维护。
新旧方案的比较
其实在枚举实例优化之前,新旧两种方案的区别不大。但是在优化之后,可以把一些处理的方法写入到枚举类中,使得我们更好的使用枚举。