1. 怎样理解枚举这个概念
- 枚举是一种取值有限的特殊的数据
- 使用关键字
enum
定义枚举,值一般是大写字母,多个值之间以逗号分隔 - 枚举类型可以定义为一个单独的文件,也可以定义在其他类内部
2. 枚举的细节
- 枚举变量的
toString()
方法返回其字面值,所有枚举类型也都有一个name()
方法,返回值与toString()
一样 - 枚举变量可以使用
equals
和==
进行比较,结果是一样的 - 枚举值是有顺序的,可以比较大小。枚举类型都有一个方法
int ordinal()
,表示枚举值在声明时的顺序,从 0 开始 - 枚举类型都实现了 Java API 中的
Comparable
接口,都可以通过方法compareTo()
与其他枚举值进行比较,其实就是比较ordinal
的大小 - 枚举变量可以用于和其他类型变量一样的地方,如方法参数、类变量、实例变量等。枚举还可以用于
switch
语句。在switch
语句中,枚举值会被转换为其对应的ordinal
值 - 在
switch
语句内部的case
值部分,枚举值不能带枚举类型前缀 - 枚举类型都有一个静态的
valueOf(String)
方法,返回字符串对应的枚举值 - 枚举类型也都有一个静态的
values()
方法,返回一个包括所有枚举值的数组,顺序与声明时的一致 - Java 是从 Java 5 才开始支持枚举的,在此之前,一般是在类中定义静态整型变量来实现类似功能
- 枚举类型本质上也是类,但由于编译器自动做了很多事情,因此它的使用更为简洁、安全和方便
3. 枚举的好处
- 枚举类型语法更为简洁,可读性更强
- 枚举类型更为安全。一个枚举类型的变量,它的值要么为
null
,要么为枚举值之一,不可能为其他值;但使用整型变量,它的值就没有办法强制,值可能就是无效的 - 枚举类型自带很多便利的方法,易于使用,对程序员更友好
4. 枚举是怎么实现的
- 枚举类型实际上会被 Java 编译器转换为一个对应的类,这个类继承了 Java API 中的
java.lang.Enum
类 Enum
类有name
和ordinal
两个实例变量,在构造方法中需要传递name()
、toString()
、ordinal()
、compareTo()
、equals()
方法都是由Enum
类根据其实例变量name
和ordinal
实现的values()
和valueOf()
方法是编译器给每个枚举类型自动添加的
5. 枚举的典型应用场景
- 实际中枚举经常会有关联的实例变量和方法,每个枚举值可能有关联的缩写和中文名称
- 需要注意的是,枚举值的定义需要放在最上面,以逗号分隔;枚举值写完之后,要以分号结尾,然后才能写其他代码
- 每个枚举值经常有一个关联的标识符(id),通常用
int
整数表示,使用整数可以节约存储空间,减少网络传输
6. 为什么不能使用枚举自带的 ordinal
值表示枚举值的 id
- 使用
ordinal
值并不是一个好的选择,因为ordinal
值会随着枚举值在定义中的位置变化而变化 - 但一般来说,我们希望 id 值和枚举值的关系保持不变,尤其是表示枚举值的 id 已经保存在了很多地方的时候
7. 枚举还有哪些高级用法
- 每个枚举值可以有关联的类定义体
- 枚举类型可以声明抽象方法,每个枚举值中可以实现该方法,也可以重写枚举类型的其他方法
- 枚举可以实现接口,也可以在接口中定义枚举
- 还可以利用枚举实现单例设计模式,参考:为什么我墙裂建议大家使用枚举来实现单例