1 引言
枚举是限定有限可能值的一种手段,使用枚举可以降低程序出错的几率,并可以提高代码的可读性与维护性。Java中的枚举并不是简单常量的集合,而是一个对象。而Java中的常量还包括类常量、接口常量,枚举常量又有什么优势呢?
2 常规方法
枚举定义
枚举类型的定义比较简单,用enum关键字加上名称和大括号包含起来的枚举值即可,如public enum CheckStaus{SUCCESS,FAILURE}.
枚举类型的每一个值都将映射到 protectedEnum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
枚举中的构造方法不能为public,只能为private,因为枚举不能实例化,即时不写修饰符也是private。
2.1 内置方法
values():返回enum实例的数组,而且该数组中的元素严格保持在enum中声明的顺序
name():返回枚举常量的名称
ordinal():返回枚举常量的序数
compareTo():比较此枚举与指定对象的顺序,在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数,该方法的自然顺序就是声明常量的顺序。
ValueOf():返回带指定名称的指定枚举类型的枚举常量
getDeclaringClas():返回与此枚举常量的枚举类型相对应的class对象
equals():判断枚举常量是否为同一个对象,可以用“==”比较
2.2 扩展方法
定义 enum 类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。EnumTest 经过反编译(javapcom.hmw.test.EnumTest 命令)之后得到的内容如下:所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。
自定义构造方法:类拥有构造器,枚举是一种特殊的类,所以枚举也可以拥有自己的构造器。但与普通类的不同之处在于枚举的构造器不可以是public的,其原因在于该构造器是提供给枚举对象中的枚举项构造时使用的,它并不需要在枚举对象之外使用
实现接口:和一般的类中使用接口一样,enum枚举中同样可以继承接口,并实现接口中的所有方法,这样做的好处在于可以更方便地对枚举中的值进行排序、比较等操作,封装性更好
成员方法:同样,枚举类型中也可以自定义成员方法
2.3 枚举集合
EnumMap是专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。
EnumSet是枚举类型的高性能Set实现。它要求放入它的枚举常量必须属于同一枚举类型。EnumSet提供了许多工厂方法以便于初始化。
3 优点和不足
优点
1.枚举常量属于稳态型,使用常量接口,必须对输入值进行检查,确定是否越界,而枚举常量可以避免此过程,在编译期限定类型,不允许发生越界的情况。
2.以将枚举本身要表达的含义与其具体的信息很好地整合起来,杜绝了传统编程语言中含义与信息分离的弊端,代码可读性强。
3.可扩展性强
不足
不同之处是:虽然枚举在很多方面都比接口常量和类常量好用,但是它有一点比不上接口常量和类常量的,就是继承,枚举类型是不能有继承的,也就是说一个枚举常量定义完毕后,除非修改重构,否则无法做扩展因为 enum 已经继承了 java.lang.Enum(java是单一继承)
4 应用
枚举通常用来表示诸如颜色、方式、类别、状态等等数目有限、形式离散、表达又极为明确的量,可以作为普通的常量使用;配合switch语句使用;自定义构造方法和成员方法,实现特殊业务逻辑需要。