第二部分:面向对象编程与 Kotlin 特性
第7章:单例与伴生对象
7.1 对象声明(object)与单例模式
1. 什么是对象声明?
在 Kotlin 中,object 关键字用于声明一个单例对象。对象声明将类的定义和实例化合并为一个步骤,确保该对象在程序运行期间只有一个实例。
object Singleton {
fun doSomething() {
println("Singleton action")
}
}
2. 单例模式的实现
Kotlin 的 object 直接支持单例模式,无需像 Java 那样手动实现双重检查锁定或静态内部类。以下特点保证了单例的唯一性:
- 对象声明是懒加载的(首次访问时初始化)。
- 线程安全(由 JVM 保证初始化过程的原子性)。
3. 使用场景
- 工具类(如日志管理器、数据库助手)
- 全局配置(如应用配置对象)
- 共享资源(如缓存管理器)
// 调用单例方法
Singleton.doSomething()
4. 对象声明的限制
- 不能定义构造函数(主构造或次构造)。
- 虽然可以实现接口或继承类,但不能作为普通类使用(无法实例化)。
5. 与伴生对象的区别
| 特性 | 对象声明 (object) | 伴生对象 (companion object) |
|---|---|---|
| 关联性 | 独立存在 | 依附于某个类 |
| 访问方式 | 直接通过对象名访问 | 通过类名访问 |
| 典型用途 | 工具类、全局单例 | 替代 Java 静态成员 |
6. 示例:实现工具类
object FileUtils {
private const val LOG_TAG = "FileUtils"
fun readFile(path: String): String {
return File(path).readText()
}
fun writeFile(path: String, content: String) {
File(path).writeText(content)
}
}
// 使用
val content = FileUtils.readFile("data.txt")
7. 单例模式的替代方案
对于需要参数化初始化的场景,可以使用:
- 依赖注入框架(如 Koin、Dagger)
- 手动实现的带参数单例(通过
lateinit或可空类型)
最佳实践:优先使用
object实现无状态工具类,对有状态单例需注意线程安全问题。
