枚举类 (Enum Classes)
枚举(Enum)是 Kotlin 中表示有限常量集合的基础工具。与 Java 相比,Kotlin 的枚举类更加灵活,支持定义属性、方法、甚至实现接口。
基础声明
最简单的枚举定义只需列出其常量成员:
kotlin
enum class Direction {
NORTH, SOUTH, WEST, EAST
}由于每个枚举常量都是一个实例,它们用逗号分隔。
携带数据的枚举
枚举类可以拥有构造函数。这使得每个常量都可以携带特定的数据。
kotlin
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF); // 如果后面有成员方法,此处的分号必选
}匿名类成员
如果枚举常量的行为需要差异化,可以利用匿名类为每个常量重写方法。
kotlin
enum class ProtocolState {
WAITING {
override fun signal() = TALKING
},
TALKING {
override fun signal() = WAITING
};
abstract fun signal(): ProtocolState
}实现接口
枚举类不能继承其他类(因为它们隐式继承了 kotlin.Enum),但可以实现一个或多个接口。
kotlin
interface Printable {
fun printData()
}
enum class DeviceStatus : Printable {
OFFLINE {
override fun printData() = println("Device is gone")
},
ONLINE {
override fun printData() = println("Device is active")
}
}常用操作与 API
完备性检查
与密封类类似,when 表达式对枚举也是完备的。如果你覆盖了所有枚举常量,则不需要 else 分支。
属性访问
每个枚举常量都内置了两个属性:
name: 常量的名称字符串。ordinal: 常量在声明中的顺序(从 0 开始)。
列表与查找
values(): 返回枚举常量的数组(在 Kotlin 1.9+ 推荐使用entries)。valueOf(value: String): 根据名称查找常量。
Enum Entries Kotlin 1.9+
传统的 values() 函数每次调用都会创建一个新的数组副本,在大规模循环中会产生性能开销。 Kotlin 1.9 引入了 entries 属性,它返回一个预先生成的、不可变的枚举常量列表。
kotlin
// 推荐写法
Direction.entries.forEach { println(it.name) }密封类 vs 枚举
这是 Kotlin 中最常见的选型问题:
| 维度 | 枚举 (Enum) | 密封类 (Sealed Class) |
|---|---|---|
| 状态多样性 | 所有常量共享相同的属性结构 | 每个子类可以拥有完全不同的属性 |
| 实例管理 | 每个常量仅有一个单例 | 子类可以有多个实例且状态各异 |
| 适用场景 | 简单的常量(如方向、周几、错误码) | 复杂的状态机(如 UI 状态、网络响应) |
总结
- 常量化:枚举是定义固定集合的利器。
- 不仅仅是常量:通过属性和方法增强其表达能力。
- entries 优先:在 Kotlin 1.9+ 环境下,优先使用
entries替代values()。 - 知难而退:如果枚举成员需要携带不一致的数据,请果断升级为密封类。