0%

Java 类的扩展(四):枚举的本质

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 类有 nameordinal 两个实例变量,在构造方法中需要传递
  • name()toString()ordinal()compareTo()equals() 方法都是由 Enum 类根据其实例变量 nameordinal 实现的
  • values()valueOf() 方法是编译器给每个枚举类型自动添加

5. 枚举的典型应用场景

  • 实际中枚举经常会有关联的实例变量和方法,每个枚举值可能有关联的缩写和中文名称
  • 需要注意的是,枚举值的定义需要放在最上面,以逗号分隔;枚举值写完之后,要以分号结尾,然后才能写其他代码
  • 每个枚举值经常有一个关联的标识符(id),通常用 int 整数表示,使用整数可以节约存储空间,减少网络传输

6. 为什么不能使用枚举自带的 ordinal 值表示枚举值的 id

  • 使用 ordinal 值并不是一个好的选择,因为 ordinal 值会随着枚举值在定义中的位置变化而变化
  • 但一般来说,我们希望 id 值和枚举值的关系保持不变,尤其是表示枚举值的 id 已经保存在了很多地方的时候

7. 枚举还有哪些高级用法

  • 每个枚举值可以有关联的类定义体
  • 枚举类型可以声明抽象方法,每个枚举值中可以实现该方法,也可以重写枚举类型的其他方法
  • 枚举可以实现接口,也可以在接口中定义枚举
  • 还可以利用枚举实现单例设计模式,参考:为什么我墙裂建议大家使用枚举来实现单例
-------------------- 本文结束感谢您的阅读 --------------------