众所周知,枚举是JDK1.5之后出来,用来代替常量的一种类,修饰类的关键字为:enum。但是你觉得枚举就仅仅如此吗?
一、为什么要引用枚举:
代码更具有可读性
允许编译时检查
避免传入无效值导致异常
数据的存储,引用更加方便直接
二、设计模式
策略模式
单例模式
1.1 代码更具有可读性
枚举可以在一个常量类里面,添加多个枚举类,将同一个业务场景下的进行归类划分,具有很高的可读性。
使用常量
public class DepartmentConstant { /** * 项目管理部 */ public static final PROJECT_MANAGER_CODE = 12; public static final PROJECT_MANAGER_NAME = "项目管理部"; /** * 综合管理部 */ public static final PROJECT_MANAGER_CODE = 13; public static final PROJECT_MANAGER_NAME = "综合管理部"; /** * 客户服务部 */ public static final PROJECT_MANAGER_CODE = 14; public static final PROJECT_MANAGER_NAME = "客户服务部"; /** * 维修部 */ public static final PROJECT_MANAGER_CODE = 15; public static final PROJECT_MANAGER_NAME = "维修部"; ....
使用枚举
public enum DepartmentEnum { PROJECT_MANAGER(12, "项目管理部"), GENERAL_MANAGER(13, "综合管理部"), CLIENT_SERVICE(14, "客户服务部"), REPAIR_SERVICE(15, "维修部"), SECURITY_MANAGER(16, "秩序维护部"), REPAIR_MANAGER(17, "维保修部"); ....
可能乍一看,感觉也不是很大的差别,但是,如果 秩序维护部 放在另一个常量类里面呢?(毕竟一个项目很少会从头到尾都是同一个人开发)
1.2 允许编译时检查
使用入参或者出参为枚举的时候,在开发编译的时候,就会有提示,你的入参/出参是否正常,是否符合预值,如果不是预期值,在编译的的时候就有提示,不给通过的。1.3 避免传入无效值导致异常
在使用 switch 逻辑判断的时候,所有的值都是在枚举定义的范围内的,不会出现枚举不存在的值,也就不用做范围控制。所有的入参都是有效的。
1.4 数据的存储,引用更加方便直接
在结构化数据存储的时候,我们常常将数据库的字段类型定义为:int 、short、 tinyint,为的就是减少数据库的负担,加强性能,在使用IN 查询的时候,可以批量操作更多的数据,同时也是为了保护数据的安全性。但是,在页面展示的时候,又需要将这些值代表的含义进行转义。这个时候,使用枚举作为实体类的字段的类型就很好了,我们可以将数据存储跟查询都是用枚举定义。
PS: 数据库还是使用 int 、short、 tinyint ,只是 ORM框架,操作的实体类对应的字段,类型为枚举类型。具体使用,可以参考下一篇文章
2.1 策略模式
枚举也是一个类,一个特殊的类,继承了Enum抽象类的类。是支持内部类的,在使用枚举作为参数的时候,我们在使用它的成员方法的时候,可以通过内部类进行策略执行。jdk的java.util.concurrent.TimeUnit 就是一个典型的例子。
/* * @since 1.5 * @author Doug Lea */public enum TimeUnit { /** * Time unit representing one thousandth of a microsecond */ NANOSECONDS { public long toNanos(long d) { return d; } public long toMicros(long d) { return d/(C1/C0); } public long toMillis(long d) { return d/(C2/C0); } public long toSeconds(long d) { return d/(C3/C0); } public long toMinutes(long d) { return d/(C4/C0); } public long toHours(long d) { return d/(C5/C0); } public long toDays(long d) { return d/(C6/C0); } public long convert(long d, TimeUnit u) { return u.toNanos(d); } int excessNanos(long d, long m) { return (int)(d - (m*C2)); } }, /** * Time unit representing one thousandth of a millisecond */ MICROSECONDS { public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } public long toMicros(long d) { return d; } public long toMillis(long d) { return d/(C2/C1); } public long toSeconds(long d) { return d/(C3/C1); } public long toMinutes(long d) { return d/(C4/C1); } public long toHours(long d) { return d/(C5/C1); } public long toDays(long d) { return d/(C6/C1); } public long convert(long d, TimeUnit u) { return u.toMicros(d); } int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } }, ... ...
2.2 单例模式
因为枚举的特性,枚举的成员,在整个生命周期,仅且实例化一次,而且默认就是public static final 修饰的,只是不需要开发者显示表明而已,而且还是保证了线程安全,在需要创建开发者模式的时候,可以使用枚举进行设计。引入网上比较经典的一个例子:
public class User { //私有化构造函数 private User(){ } //定义一个静态枚举类 static enum SingletonEnum{ //创建一个枚举对象,该对象天生为单例 INSTANCE; private User user; //私有化枚举的构造函数 private SingletonEnum(){ user=new User(); } public User getInstnce(){ return user; } } //对外暴露一个获取User对象的静态方法 public static User getInstance(){ return SingletonEnum.INSTANCE.getInstnce(); }}
下一篇:讲述:Springboot如何使用枚举