Kotlin常量
外观
Kotlin常量[编辑 | 编辑源代码]
简介[编辑 | 编辑源代码]
在Kotlin中,常量(Constants)是指在程序运行期间其值不可改变的标识符。Kotlin提供了两种主要方式声明常量:
- 编译时常量(使用`const val`)
- 运行时常量(使用`val`)
常量用于存储程序中不会改变的值(如数学常数、配置参数等),能提高代码可读性和安全性。
编译时常量与运行时常量[编辑 | 编辑源代码]
特性 | `const val` | `val` |
---|---|---|
初始化时机 | 编译时 | 运行时 |
作用域 | 顶层或伴生对象 | 任何作用域 |
数据类型限制 | 仅限基本类型和String | 任意类型 |
是否内联 | 是(直接替换为字面量) | 否 |
声明语法[编辑 | 编辑源代码]
编译时常量[编辑 | 编辑源代码]
必须满足以下条件: 1. 声明在顶层或伴生对象中 2. 使用基本类型或String初始化 3. 没有自定义getter
// 顶层声明
const val PI = 3.1415926535
const val APP_NAME = "MyKotlinApp"
class Constants {
companion object {
const val MAX_USERS = 1000
}
}
运行时常量[编辑 | 编辑源代码]
使用`val`关键字声明,在首次访问时初始化:
val currentRuntimeVersion = System.getProperty("java.version")
class User {
val createdAt: LocalDateTime = LocalDateTime.now()
}
使用场景对比[编辑 | 编辑源代码]
实际案例[编辑 | 编辑源代码]
场景1:数学计算
const val GOLDEN_RATIO = 1.6180339887
fun calculateGoldenRectangle(width: Double): Double {
return width * GOLDEN_RATIO
}
场景2:Android开发
object ApiConfig {
const val BASE_URL = "https://api.example.com"
const val TIMEOUT_SECONDS = 30
}
class UserService {
fun fetchUsers(): List<User> {
val retrofit = Retrofit.Builder()
.baseUrl(ApiConfig.BASE_URL)
.timeout(ApiConfig.TIMEOUT_SECONDS)
.build()
// ... 其他实现
}
}
性能考量[编辑 | 编辑源代码]
编译时常量会在字节码中被直接替换为字面量,这带来以下优势:
- 零运行时开销
- 可以被注解处理器使用
- 允许跨模块使用
数学表达式示例:
最佳实践[编辑 | 编辑源代码]
1. 优先使用`const val`存储真正的不可变值 2. 对需要复杂初始化的值使用`val` 3. 常量命名遵循`UPPER_SNAKE_CASE`规范 4. 将相关常量组织在单例对象或伴生对象中
错误示例[编辑 | 编辑源代码]
// 错误:const不能用于局部变量
fun calculate() {
const val TAX_RATE = 0.2 // 编译错误
}
// 错误:const不能用于非基本类型
const val user = User("Alice") // 编译错误
进阶主题[编辑 | 编辑源代码]
常量传播优化[编辑 | 编辑源代码]
Kotlin编译器会对常量表达式进行优化:
const val WIDTH = 100
const val HEIGHT = 200
val area = WIDTH * HEIGHT // 编译时会直接计算为20000
跨模块常量[编辑 | 编辑源代码]
在多模块项目中,可以使用`public const val`使常量对其他模块可见:
```kotlin // 在common模块中 public const val SHARED_CONST = "Value"
// 在其他模块中可以直接引用 ```
总结[编辑 | 编辑源代码]
Kotlin的常量系统提供了灵活的不可变值管理方式。关键要点:
- 区分`const val`和`val`的使用场景
- 编译时常量有严格的限制条件
- 合理使用常量能提升代码质量和性能
- 遵循命名规范和组织原则
通过本文的学习,你应该能够根据具体需求选择适当的常量声明方式,并理解其背后的原理和最佳实践。