在 Kotlin 中,枚举类(Enum Class) 用于定义一组有限的命名常量,支持附加属性、方法及自定义行为。以下是其核心特性、用法及示例:
一、枚举类的基本定义
1. 基础语法
enum class Direction {
NORTH, SOUTH, EAST, WEST // 枚举常量
}
// 使用示例
val currentDirection = Direction.NORTH
println(currentDirection) // 输出: NORTH
2. 带属性的枚举类
每个枚举常量可携带额外属性(需定义构造函数):
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}
// 访问属性
println(Color.RED.rgb) // 输出: 16711680(即 0xFF0000 的十进制值)
二、枚举类的高级用法
1. 实现接口
枚举类可实现接口,为不同常量定义不同行为:
interface Action {
fun execute()
}
enum class Operation : Action {
ADD {
override fun execute() = println("执行加法")
},
SUBTRACT {
override fun execute() = println("执行减法")
}
}
// 调用
Operation.ADD.execute() // 输出: 执行加法
2. 匿名类与自定义方法
每个枚举常量可通过匿名类覆盖方法或添加新逻辑:
enum class Planet(val mass: Double) {
EARTH(5.97e24) {
override fun description() = "人类的家园"
},
MARS(6.39e23) {
override fun description() = "未来的殖民地"
};
abstract fun description() // 抽象方法
}
// 使用
println(Planet.EARTH.description()) // 输出: 人类的家园
三、枚举类的常用方法
1. 遍历枚举常量
通过 values() 或 enumValues<T>() 获取所有枚举实例:
enum class Weekday { MON, TUE, WED, THU, FRI }
// 遍历
Weekday.values().forEach { println(it) }
// 输出: MON, TUE, WED, THU, FRI
2. 从字符串解析枚举
使用 valueOf() 或安全方法 enumValueOfOrNull(Kotlin 1.9+):
val day = Weekday.valueOf("MON") // 严格匹配,不区分大小写
val safeDay = enumValueOfOrNull<Weekday>("monday") // 返回 null
四、when 表达式与枚举类
利用 when 的穷尽性检查,确保处理所有枚举分支:
fun getWeather(direction: Direction) = when (direction) {
Direction.NORTH -> "寒冷"
Direction.SOUTH -> "炎热"
Direction.EAST, Direction.WEST -> "多风"
}
println(getWeather(Direction.EAST)) // 输出: 多风
五、注意事项
- 性能与内存
枚举类比普通常量占用更多内存(每个实例为对象),在性能敏感场景(如 Android)需谨慎使用。 - 单例特性
每个枚举常量在 JVM 中是单例,线程安全且序列化友好。 - 构造函数限制
枚举类的主构造函数只能是private(默认隐式),不可在类外实例化。
六、实际应用场景
1. 状态管理
enum class DownloadStatus {
IDLE, RUNNING, COMPLETED, FAILED
}
fun handleStatus(status: DownloadStatus) {
when (status) {
DownloadStatus.COMPLETED -> println("下载完成")
DownloadStatus.FAILED -> println("下载失败")
else -> println("状态未处理")
}
}
2. 类型安全的配置
enum class HttpMethod {
GET, POST, PUT, DELETE
}
fun sendRequest(method: HttpMethod, url: String) {
// 根据 method 发送对应 HTTP 请求
}
七、与密封类(Sealed Class)的对比
| 特性 | 枚举类(Enum Class) | 密封类(Sealed Class) |
|---|---|---|
| 实例数量 | 固定数量的常量(编译时确定) | 子类数量固定,但每个子类可携带不同数据 |
| 数据携带能力 | 只能通过构造函数传递固定属性 | 每个子类可定义独立属性及结构 |
| 适用场景 | 简单常量集合(如状态、类型) | 复杂多态数据(如网络请求结果、UI 状态) |
总结
- 优先使用枚举类:当需要一组固定常量且需附加属性或方法时。
- 替代方案考虑:若需更灵活的数据结构,使用密封类或普通类。
- 注意性能影响:在资源受限环境中评估枚举类的使用必要性。